ALMaSS  1.0
The Animal, Landscape and Man Simulation System
OptimisingFarm Class Reference

A farm that carries out crop, pesticide and fertilizer planning using simplified optimisation or other decision startegies. More...

#include <farm.h>

Inheritance diagram for OptimisingFarm:
Farm AnimalFarm NonAnimalFarm OptimisingCattleFarm OptimisingPigFarm OptimisingOtherFarm OptimisingPlantFarm

Classes

struct  CropSort
 Struct used for sorting crops. More...
 
struct  MakeRotation
 Struct used only in Bedriftsmodel crop type mode for creating m_rotation vector. Bool member used for marking the element of a vector as already assigned a TTypesOfVegetation crop type. More...
 
struct  reverseSort
 Struct redefining operator < - used for sorting crops. More...
 

Public Member Functions

 OptimisingFarm (FarmManager *a_myfarmmanager, int a_No)
 The constructor. More...
 
virtual ~OptimisingFarm ()
 
TTypesOfOptFarms Get_farmType (void)
 
TTypesOfSoils Get_soilType (void)
 
TTypesOfFarmSize Get_farmSize (void)
 
int Get_farmRealID (void)
 
int Get_soilSubType (void)
 
int Get_almass_no (void)
 
CropOptimisedGet_crop (int i)
 
int Get_cropsSize (void)
 
void Set_Livestock (Livestock *p_lvs)
 
void Set_Crop (CropOptimised *p_crop)
 
void Set_Neighbour (OptimisingFarm *farm)
 
int Get_NeighboursSize (void)
 
OptimisingFarmGet_Neighbour (int i)
 
vector< AlmassCropGet_rotational_crops ()
 
vector< AlmassCropGet_rotational_crops_visible ()
 
double Get_actual_profit ()
 
double Get_actual_aggregated_yield ()
 
int GetFarmCentroidX ()
 
int GetFarmCentroidY ()
 
void Set_main_goal (TTypeOfFarmerGoal a_goal)
 
TTypeOfFarmerGoal Get_main_goal ()
 
void Set_animals_no (int a_number)
 
int Get_decision_mode_counters (int index)
 
bool Harvest (LE *a_field, double a_user, int a_days)
 OptimisingFarm's virtual version of Farm::Harvest(). Saves information on biomass of a crop at harvest. More...
 
void Match_crop_to_field (LE *a_field)
 Finds a crop to be grown on a given field next year. More...
 
OptimisingFarmFind_neighbour_to_imitate ()
 Picks randomly a farmer to imitate/compare with. It chooses among neighbouring farmers with similar farms. More...
 
void ActualProfit ()
 Function that determines actual crop yields and profit in a given year. More...
 
void Save_last_years_crops ()
 It saves the OptimisingFarm::m_rotational_crops in a vector m_rotational_crops_visible which is accessible for other farmers if they decide to copy it in the following year. More...
 
void ChooseDecisionMode ()
 Function determines which decision mode to use. The choice depends on the values of need satisfaction and uncertainty. More...
 
virtual bool Spraying_herbicides (TTypesOfVegetation a_tov_type)
 Returns true if a farmer decided to treat a given crop with herbicides. More...
 
virtual bool Spraying_fungins (TTypesOfVegetation a_tov_type)
 Returns true if a farmer decided to treat a given crop with fung- and insecticides. More...
 
virtual double Prob_multiplier ()
 Used when determining whether there should be a spraying event (i.e. pesticides application) or not. For yield maximizer it increases the chance of spraying event to account for his 'just in case' spraying. More...
 
void Init (ofstream *ap_output_file)
 Function carrying out the initial calculations at a farm level (including the initial optimisation). More...
 
- Public Member Functions inherited from Farm
virtual void Management (void)
 Starts the main management loop for the farm and performs some error checking. More...
 
void AddField (LE *a_newfield)
 Adds a field to a farm. More...
 
void RemoveField (LE *a_field)
 Removes a field from a farm. More...
 
 Farm (FarmManager *a_manager)
 Farm constructor - creates an instance of each possible crop type. More...
 
virtual ~Farm (void)
 Farm destructor - deletes all crop instances and empties event queues. More...
 
void SetFarmNumber (int a_farm_num)
 
int GetFarmNumber (void)
 
void Assign_rotation (vector< TTypesOfVegetation >a_new_rotation)
 
polylistListOpenFields (int a_openness)
 Returns a list of fields with openness above a_openness. More...
 
void Centroids ()
 Finds farm's centroids - x and y. More...
 
int GetNoFields ()
 Returns the number of the fields owned. More...
 
int GetNoOpenFields (int a_openness)
 Returns the number of the fields above an openness of a_openness. More...
 
int GetAreaOpenFields (int a_openness)
 Returns the area of the fields above an openness of a_openness. More...
 
APoint GetValidCoords ()
 Returns the valid coordinates of the first field owned by a farm. More...
 
int GetMaxOpenness ()
 Returns the maximum openness score of the fields. More...
 
virtual bool SleepAllDay (LE *a_field, double a_user, int a_days)
 Nothing to to today on a_field. More...
 
virtual bool AutumnPlough (LE *a_field, double a_user, int a_days)
 Carry out a ploughing event in the autumn on a_field. More...
 
virtual bool StubblePlough (LE *a_field, double a_user, int a_days)
 Carry out a stubble ploughing event on a_field. This is similar to normal plough but shallow (normally 6-8cm, is special cases up to 12-15cm). Done as a part of after-harvest treatments (instead of stubble cultivation) More...
 
virtual bool StubbleCultivatorHeavy (LE *a_field, double a_user, int a_days)
 Carry out a stubble cultivation event on a_field. This is non-inversion type of cultivation which can be done instead of autumn plough (on a depth up to 40 cm even, if necessary) More...
 
virtual bool AutumnHarrow (LE *a_field, double a_user, int a_days)
 Carry out a harrow event in the autumn on a_field. More...
 
virtual bool AutumnRoll (LE *a_field, double a_user, int a_days)
 Carry out a roll event in the autumn on a_field. More...
 
virtual bool PreseedingCultivator (LE *a_field, double a_user, int a_days)
 Carry out preseeding cultivation on a_field (tilling set including cultivator and string roller to compact soil) More...
 
virtual bool PreseedingCultivatorSow (LE *a_field, double a_user, int a_days)
 Carry out preseeding cultivation together with sow on a_field (tilling and sowing set including cultivator and string roller to compact soil) More...
 
virtual bool AutumnSow (LE *a_field, double a_user, int a_days)
 Carry out a sowing event in the autumn on a_field. More...
 
virtual bool WinterPlough (LE *a_field, double a_user, int a_days)
 Carry out a ploughing event in the winter on a_field. More...
 
virtual bool DeepPlough (LE *a_field, double a_user, int a_days)
 Carry out a deep ploughing event on a_field. More...
 
virtual bool SpringPlough (LE *a_field, double a_user, int a_days)
 Carry out a ploughing event in the spring on a_field. More...
 
virtual bool SpringHarrow (LE *a_field, double a_user, int a_days)
 Carry out a harrow event in the spring on a_field. More...
 
virtual bool SpringRoll (LE *a_field, double a_user, int a_days)
 Carry out a roll event in the spring on a_field. More...
 
virtual bool SpringSow (LE *a_field, double a_user, int a_days)
 Carry out a sowing event in the spring on a_field. More...
 
virtual bool SpringSowWithFerti (LE *a_field, double a_user, int a_days)
 Carry out a sowing event with start fertilizer in the spring on a_field. More...
 
virtual bool GrowthRegulator (LE *a_field, double a_user, int a_days)
 Apply growth regulator to a_field. More...
 
virtual bool ProductApplication (LE *a_field, double a_user, int a_days, double a_applicationrate, PlantProtectionProducts a_ppp)
 Apply test pesticide to a_field. More...
 
virtual bool ProductApplication_DateLimited (LE *a_field, double, int, double a_applicationrate, PlantProtectionProducts a_ppp)
 Special pesticide trial functionality. More...
 
virtual bool Molluscicide (LE *a_field, double a_user, int a_days)
 Apply molluscidie to a_field. More...
 
virtual bool RowCultivation (LE *a_field, double a_user, int a_days)
 Carry out a harrowing between crop rows on a_field. More...
 
virtual bool Strigling (LE *a_field, double a_user, int a_days)
 Carry out a mechanical weeding on a_field. More...
 
virtual bool StriglingSow (LE *a_field, double a_user, int a_days)
 Carry out a mechanical weeding followed by sowing on a_field. More...
 
virtual bool StriglingHill (LE *a_field, double a_user, int a_days)
 Carry out a mechanical weeding on a_field followed by hilling up (probably on potatoes) More...
 
virtual bool HillingUp (LE *a_field, double a_user, int a_days)
 Do hilling up on a_field, probably of potatoes. More...
 
virtual bool Water (LE *a_field, double a_user, int a_days)
 Carry out a watering on a_field. More...
 
virtual bool Swathing (LE *a_field, double a_user, int a_days)
 Cut the crop on a_field and leave it lying (probably rape) More...
 
virtual bool HarvestLong (LE *a_field, double a_user, int a_days)
 Carry out a harvest on a_field. More...
 
virtual bool CattleOut (LE *a_field, double a_user, int a_days)
 Start a grazing event on a_field today. More...
 
virtual bool CattleOutLowGrazing (LE *a_field, double a_user, int a_days)
 Start a extensive grazing event on a_field today. More...
 
virtual bool CattleIsOut (LE *a_field, double a_user, int a_days, int a_max)
 Generate a 'cattle_out' event for every day the cattle are on a_field. More...
 
virtual bool CattleIsOutLow (LE *a_field, double a_user, int a_days, int a_max)
 Generate a 'cattle_out_low' event for every day the cattle are on a_field. More...
 
virtual bool PigsOut (LE *a_field, double a_user, int a_days)
 Generate a 'pigs_out' event for every day the cattle are on a_field. More...
 
virtual bool PigsAreOut (LE *a_field, double a_user, int a_days)
 Start a pig grazing event on a_field today or soon. More...
 
virtual bool PigsAreOutForced (LE *a_field, double a_user, int a_days)
 Start a pig grazing event on a_field today - no exceptions. More...
 
virtual bool CutToHay (LE *a_field, double a_user, int a_days)
 Carry out hay cutting on a_field. More...
 
virtual bool CutWeeds (LE *a_field, double a_user, int a_days)
 Carry out weed topping on a_field. More...
 
virtual bool CutToSilage (LE *a_field, double a_user, int a_days)
 Cut vegetation for silage on a_field. More...
 
virtual bool CutOrch (LE *a_field, double a_user, int a_days)
 Cut vegetation on orchard crop. //based on cut to silage - values from cutting function of orchard. More...
 
virtual bool StrawChopping (LE *a_field, double a_user, int a_days)
 Carry out straw chopping on a_field. More...
 
virtual bool HayTurning (LE *a_field, double a_user, int a_days)
 Carry out hay turning on a_field. More...
 
virtual bool HayBailing (LE *a_field, double a_user, int a_days)
 Carry out hay bailing on a_field. More...
 
virtual bool BurnStrawStubble (LE *a_field, double a_user, int a_days)
 Burn stubble on a_field. More...
 
virtual bool StubbleHarrowing (LE *a_field, double a_user, int a_days)
 Carry out stubble harrowing on a_field. More...
 
virtual bool FP_NPKS (LE *a_field, double a_user, int a_days)
 Apply NPKS fertilizer, on a_field owned by an arable farmer. More...
 
virtual bool FP_NPK (LE *a_field, double a_user, int a_days)
 Apply NPK fertilizer, on a_field owned by an arable farmer. More...
 
virtual bool FP_PK (LE *a_field, double a_user, int a_days)
 Apply PK fertilizer, on a_field owned by an arable farmer. More...
 
virtual bool FP_LiquidNH3 (LE *a_field, double a_user, int a_days)
 Apply liquid ammonia fertilizer to a_field owned by an arable farmer. More...
 
virtual bool FP_Slurry (LE *a_field, double a_user, int a_days)
 Apply slurry to a_field owned by an arable farmer. More...
 
virtual bool FP_ManganeseSulphate (LE *a_field, double a_user, int a_days)
 Apply Manganse Sulphate to a_field owned by an arable farmer. More...
 
virtual bool FP_AmmoniumSulphate (LE *a_field, double a_user, int a_days)
 Apply Ammonium Sulphate to a_field owned by an arable farmer. More...
 
virtual bool FP_Manure (LE *a_field, double a_user, int a_days)
 Spread manure on a_field owned by an arable farmer. More...
 
virtual bool FP_GreenManure (LE *a_field, double a_user, int a_days)
 Spread green manure on a_field owned by an arable farmer. More...
 
virtual bool FP_Sludge (LE *a_field, double a_user, int a_days)
 Spread sewege on a_field owned by an arable farmer. More...
 
virtual bool FP_RSM (LE *a_field, double a_user, int a_days)
 RSM (ammonium nitrate solution) applied on a_field owned by an arable farmer. More...
 
virtual bool FP_Calcium (LE *a_field, double a_user, int a_days)
 Calcium applied on a_field owned by an arable farmer. More...
 
virtual bool FA_NPKS (LE *a_field, double a_user, int a_days)
 Apply NPKS fertilizer, on a_field owned by a stock farmer. More...
 
virtual bool FA_NPK (LE *a_field, double a_user, int a_days)
 Apply NPK fertilizer to a_field owned by an stock farmer. More...
 
virtual bool FA_PK (LE *a_field, double a_user, int a_days)
 Apply PK fertilizer to a_field owned by an stock farmer. More...
 
virtual bool FA_Slurry (LE *a_field, double a_user, int a_days)
 Spready slurry on a_field owned by an stock farmer. More...
 
virtual bool FA_ManganeseSulphate (LE *a_field, double a_user, int a_days)
 Apply manganese sulphate to a_field owned by an stock farmer. More...
 
virtual bool FA_AmmoniumSulphate (LE *a_field, double a_user, int a_days)
 Apply ammonium sulphate to a_field owned by an stock farmer. More...
 
virtual bool FA_Manure (LE *a_field, double a_user, int a_days)
 Spread manure on a_field owned by an stock farmer. More...
 
virtual bool FA_GreenManure (LE *a_field, double a_user, int a_days)
 Spread green manure on a_field owned by an stock farmer. More...
 
virtual bool FA_Sludge (LE *a_field, double a_user, int a_days)
 Spread sewege sludge on a_field owned by an stock farmer. More...
 
virtual bool FA_RSM (LE *a_field, double a_user, int a_days)
 RSM (ammonium nitrate solution) applied on a_field owned by a stock farmer. More...
 
virtual bool FA_Calcium (LE *a_field, double a_user, int a_days)
 Calcium applied on a_field owned by a stock farmer. More...
 
virtual bool Biocide (LE *a_field, double a_user, int a_days)
 Biocide applied on a_field. More...
 
virtual bool BedForming (LE *a_field, double a_user, int a_days)
 Do bed forming up on a_field, probably of carrots. More...
 
virtual bool ShallowHarrow (LE *a_field, double a_user, int a_days)
 Carry out a shallow harrow event on a_field, e.g., after grass cutting event. More...
 
virtual bool HeavyCultivatorAggregate (LE *a_field, double a_user, int a_days)
 Carry out a heavy cultivation event on a_field. This is non-inversion type of cultivation which can be done after fertilizers application on spring for a spring crop. More...
 
virtual bool FlowerCutting (LE *a_field, double a_user, int a_days)
 Flower cutting applied on a_field. More...
 
virtual bool BulbHarvest (LE *a_field, double a_user, int a_days)
 Carry out a bulb harvest on a_field. More...
 
virtual bool StrawCovering (LE *a_field, double a_user, int a_days)
 Straw covering applied on a_field. More...
 
virtual bool StrawRemoval (LE *a_field, double a_user, int a_days)
 Straw covering applied on a_field. More...
 
void AddNewEvent (TTypesOfVegetation a_event, long a_date, LE *a_field, int a_todo, long a_num, bool a_lock, int a_start, bool a_first_year, TTypesOfVegetation a_crop)
 Adds an event to the event queue for a farm. More...
 
bool DoIt (double a_probability)
 Return chance out of 0 to 100. More...
 
bool DoIt_prob (double a_probability)
 Return chance out of 0 to 1. More...
 
TTypesOfFarm GetType (void)
 
int GetArea (void)
 Returns the area of arable fields owned by that farm. More...
 
int GetTotalArea (void)
 Returns the area of all fields owned by that farm. More...
 
double GetAreaDouble (void)
 Returns the area of arable fields owned by that farm. More...
 
bool IsStockFarmer (void)
 
virtual void MakeStockFarmer (void)
 
int GetIntensity (void)
 
APoint GetCentroids ()
 
TTypesOfVegetation GetPreviousCrop (int a_index)
 
TTypesOfVegetation GetCrop (int a_index)
 
TTypesOfVegetation GetNextCrop (int a_index)
 
void AddHunter (Hunter *a_hunter)
 
void RemoveHunter (Hunter *a_hunter)
 

Protected Member Functions

virtual void InitiateManagement (void)
 Kicks off the farm's management. More...
 
void Initialize (FarmManager *a_pfm)
 Assigns to each farm its farm type, farm size, farm's real ID number, and soil type. It creates livestock and crops. More...
 
virtual void HandleEvents (void)
 If there are events to carry out do this, and perhaps start a new crop. More...
 
virtual bool FungicideTreat (LE *a_field, double, int a_days)
 Carries out fungicide application. Saves information on each application for a given crop. More...
 
virtual bool InsecticideTreat (LE *a_field, double, int a_days)
 Carries out insecticide application. Saves information on each application for a given crop. More...
 
virtual bool HerbicideTreat (LE *a_field, double, int a_days)
 Carries out herbicide application. Saves information on each application for a given crop. More...
 
virtual void createCropsLists (int a_foobar)
 Creates lists of crops. More...
 
void createVariableCrops (int a_foobar)
 Creates a list of pointers to all variable crops included in the optimisation and a list of pointers to fixed crops. More...
 
void FarmLevelCalculation ()
 Calls functions determining farm level values before the initial optimisation. More...
 
void OptimiseFarm (int a_foobar)
 Carries out the whole farm optimisation. More...
 
void Check_SG_and_CGG ()
 Modifies areas of SeedGrass1 and SeedGrass2, CloverGrassGrazed1 and CloverGrassGrazed2 to be even. Used only in ALMaSS crops mode (in Bedriftsmodel (original farm optimization model) crops mode this is taken care of in Translate_crops_to_almass()). More...
 
void findTotalArea ()
 Determines m_totalArea of a farm. More...
 
void findTotalNanim ()
 Determines total animal fertilizer (m_totalNanim) available at a farm. More...
 
void findNanim ()
 Determines amount of animal fertilizer per ha (m_Nanim) at a farm. More...
 
virtual void findFodderDemand ()
 Determines farm's total demand for fodder (m_totalFUdemand). More...
 
virtual void preventCashCrops ()
 Prevents small cattle farms from growing cash crops and maize silage. More...
 
void optimizeCrops (int a_foobar)
 Carries out crop optimisation at a farm. More...
 
void findFertilizer (CropOptimised *a_crop, int a_foobar, double benefit)
 Determines the optimal amounts of: total fertilizer (CropOptimised::m_n) and purchased fertilizer (CropOptimised::m_nt) for a given crop at a farm. More...
 
void findResponse (CropOptimised *a_crop, int a_foobar)
 Determines the response (CropOptimised::m_resp) of a crop at a farm. More...
 
void findBIs (CropOptimised *a_crop, double benefit)
 Determines the optimal Treatment frequency indices (behandling index, BI in Danish) (CropOptimised::m_BIHerb, CropOptimised::m_BIFi, CropOptimised::m_BI) for a given crop at a farm. More...
 
void fixBI ()
 Sets values of Treatment frequency indices (BI) for crops with fixed amount of pesticides (CropOptimised::m_BIHerb for FodderBeet and both CropOptimised::m_BIHerb and CropOptimised::m_BIFi for PotatoesIndustry and Potatoes). More...
 
void findMWeedControl (CropOptimised *a_crop)
 Determines the optimal mechanical weed control means (CropOptimised::m_grooming, CropOptimised::m_hoeing, CropOptimised::m_weeding) for a given crop at a farm. More...
 
void findYieldLoss (CropOptimised *a_crop)
 Determines the yield losses (CropOptimised::m_lossHerb, CropOptimised::m_lossFi, CropOptimised::m_totalLoss) for a given crop at a farm. More...
 
void findGrossMargin (CropOptimised *a_crop, int a_foobar, double benefit)
 Determines the gross margin (CropOptimised::m_GM) for a given crop at a farm. More...
 
void assignFixed ()
 Adds areas of fixed crops to the variable m_assigned. For each fixed crop it saves its area under variable CropOptimised::m_areaPercent. More...
 
void sumMinAreas ()
 Adds minimum required areas of variable crops to the variable m_assigned. More...
 
virtual void determineAreas (int a_foobar)
 Determines areas of variable crops. More...
 
void determineAreas_ha (vector< CropOptimised * >crops)
 Determines areas of crops in ha. More...
 
virtual void checkRestrictions ()
 Checks if the restrictions are fulfilled and corrects crops' areas if necessary. More...
 
virtual void checkWinterRotation1 ()
 Checks if the restriction on a winter rotation is fulfilled. More...
 
virtual void checkWinterCrops ()
 Checks if the restriction on a max. share of winter crops is fulfilled. More...
 
void setRotationCropsAtMax ()
 Increases area of winter rotation crops to their max. allowed area. More...
 
double crop_parameter (int index, string par_name)
 Reads in crop parameters that do NOT vary with any farm level parameters. More...
 
CropOptimisedfindCropByName (string crop_name)
 Returns a pointer to a crop whose name is specified as the argument (bedriftsmodel, i.e. original farm optimization model, crops mode). More...
 
CropOptimisedfindCropByName_almass (string crop_name)
 Returns a pointer to almass crop whose name is specified as the argument (ALMaSS crops mode). More...
 
CropOptimisedfindCropByName_almass (TTypesOfVegetation a_tov_type)
 Returns a pointer to almass crop whose tov type is specified as the argument. More...
 
double total (TTypesOfCropVariables variable_name)
 Function for determining total values per farm after initial optimisation. More...
 
void sortCrops (vector< CropSort > &cropsToSort, string sortingKey)
 Sorts structs of type CropSort. More...
 
void randomizeCropList (vector< CropSort > &listToRandomize, string key)
 Swaps randomly elements of the list holding same values of the key (according to which the list was previosuly sorted). More...
 
virtual void increaseCrops (vector< CropSort >cropsToIncrease, double &howMuchToIncrease)
 Increases area of crops by a specified number. More...
 
virtual void decreaseCrops (vector< CropSort >cropsToDecrease, double &howMuchToDecrease)
 Decreases area of a crops by a specified number. More...
 
void Print_FarmVariables (ofstream *ap_output_file)
 Prints farm-level variables to a text file (one file for all farms). More...
 
void Make_rotations ()
 Creates m_rotation. Not used in ALMaSS crop mode. More...
 
void Check_if_area_100 ()
 Checks if the sum of crops' areaPercent is 100%. More...
 
void Translate_crops_to_almass ()
 Translates crops from Bedriftsmodel (original farm optimization model) to Almass crops. Used in Bedriftsmodel crop mode. More...
 
void Make_almass_crops_vector ()
 Creates a vector storing crops with positive area. Used in ALMaSS crop mode. More...
 
void Make_rotational_crops ()
 Creates a vector m_rotational_crops using the results of optimisation. More...
 
void Print_rotations (ofstream *ap_output_file)
 Prints the content of a farm's m_rotation. Not used in ALMaSS crop mode. More...
 
- Protected Member Functions inherited from Farm
int GetFirstDate (TTypesOfVegetation a_tov)
 Gets the start date for a crop type. More...
 
int GetNextCropStartDate (LE *a_field, TTypesOfVegetation &a_curr_veg)
 Returns the start date of the next crop in the rotation. More...
 
virtual int GetFirstCropIndex (TTypesOfLandscapeElement a_type)
 Gets the first crop for the farm. More...
 
virtual int GetNextCropIndex (int a_rot_index)
 Returns the next crop in the rotation. More...
 
bool LeSwitch (FarmEvent *ev)
 Call do function for any crop with an outstanding event. Signal if the crop has terminated. More...
 
void CheckRotationManagementLoop (FarmEvent *ev)
 
void ReadRotation (std::string fname)
 Reads a rotation file into the rotation. More...
 
void AssignPermanentCrop (TTypesOfVegetation tov, int pct)
 Used to assign a permanent crop to an otherwise rotational field polygon. More...
 
int InvIntPartition (vector< tpct > *items, int target)
 Finds all possible sums of the integers in the items array. More...
 

Protected Attributes

TTypeOfFarmerGoal m_main_goal
 Farmer's main goal (determined by a farmer's type) . More...
 
vector< OptimisingFarm * > m_neighbours
 Vector of pointers to the farms considered neighbours (fulfilling the neighbourship condition) of a given farm. More...
 
double m_need_satisfaction_level
 Farmer's actual satisfaction level. More...
 
double m_certainty_level
 Farmer's certainty level. More...
 
vector< int > m_decision_mode_counters
 Vector with counters for each decision mode. 0 - imitation, 1 - social comparison, 2 - repeat, 3 - deliberation. More...
 
double m_actual_profit
 An actual profit realised at a farm in a given year. More...
 
double m_exp_profit
 An expected farm's profit for a given year. More...
 
double m_actual_income
 An actual income at a farm in a given year. More...
 
double m_exp_income
 An expected farm's income at a farm in a given year. More...
 
double m_actual_costs
 Actual costs at a farm in a given year. More...
 
double m_exp_costs
 Expected costs at a farm in a given year. More...
 
double m_actual_aggregated_yield
 Actual aggregated yield at a farm in a given year. More...
 
double m_exp_aggregated_yield
 Expected aggregated yield at a farm in a given year. More...
 
vector< double > m_previous_profits
 Vector of profits from previous years. More...
 
vector< double > m_previous_incomes
 Vector of incomes from previous years. More...
 
vector< double > m_previous_costs
 Vector of costs from previous years. More...
 
vector< double > m_previous_aggregated_yields
 Vector of aggregated yields from previous years. More...
 
vector< double > m_previous_satisfaction_levels
 Vector of satisfaction levels in five previous years. More...
 
OptimisingFarmm_previously_imitated_neighbour
 The neighbouring farmer whose crops might be copied in imitation and social comparison decision modes. More...
 
vector< double > m_animals_numbers
 Vector for storing numbers of animals at a farm in previous years (3). More...
 
bool force_deliberation
 If set to true, a farm must use deliberation as a decision strategy. More...
 
int animals_no
 Holds the number of animals in a farm at a particular day in a year (depends on a species). More...
 
vector< Livestock * > m_livestock
 Vector of pointers to animals belonging to a farm. More...
 
vector< CropOptimised * > m_crops
 Vector of pointers to all crops. More...
 
vector< CropSortm_variableCrops
 Vector of structs containing pointers to crops which are not fixed. More...
 
vector< CropSortm_variableCrops2
 Vector of structs containing pointers to crops which are not fixed and: in case of the winter rotation restriction - exclude winter rotation crops, in case of the cattle rotation restriction - exclude the three crops that form the condition of the restriction and winter wheat. More...
 
vector< CropOptimised * > m_grownVariableCrops
 Vector of pointers to variable crops that are grown on area larger than areaMin (after determineAreas function was called). More...
 
vector< CropOptimised * > m_fixedCrops
 Vector of pointers to fixed crops. More...
 
vector< CropSortm_rotationCrops
 Vector of structs containing pointers to (winter) rotation crops. More...
 
vector< CropSortm_winterCrops
 Vector of structs containing pointers to winter crops. More...
 
vector< AlmassCropm_crops_almass
 Vector of structs with almass type crops with positive areas in % (result of optimisation). More...
 
vector< AlmassCropm_rotational_crops
 Vector of structs with almass type crops with positive areas in % (result of optimisation): includes only rotational crops. More...
 
vector< AlmassCropm_rotational_crops_copy
 A copy of m_rotational_crops used when matching crops to fields. More...
 
vector< AlmassCropm_rotational_crops_visible
 Stores a copy of m_rotational_crops from a previous year and is accessible to farmers who want to copy this farm's crops (in imitation or social comparison decision mode). More...
 
TTypesOfOptFarms m_farmType
 Farm's type (cattle, pig, plant, other). More...
 
TTypesOfSoils m_soilType
 Farm's soil type (sandy, clay, other). More...
 
TTypesOfFarmSize m_farmSize
 Scale of the farm - business (size above 10 ha) or private (size below 10 ha). More...
 
int m_farmRealID
 Farm's real ID number. More...
 
int m_soilSubType
 Farm's soil subtype. Defined only for cattle farms on sandy soil (0-bad, 1-good, 2-undefined). More...
 
int m_almass_no
 Farm's almass number. More...
 
double m_totalArea
 Total area of a farm. A sum of initial crop areas (if in bedriftsmodel, i.e. original farm optimization model, crops mode) or a sum of farm's fields area (if in ALMaSS crops mode). [ha]. More...
 
double m_totalArea_original
 Total area of a farm as in bedriftsmodel, i.e. original farm optimization model. [ha]. More...
 
double m_area_scaling_factor
 Factor used to scale areas of fixed crops and livestock numbers. Used to adjust these values to the farm's area used in ALMaSS crops mode. More...
 
double m_totalNanim
 Total animal fertilizer at a farm. A sum of Livestock::m_NanimUsable (from all types of livestock). [kg]. More...
 
double m_Nanim
 Amount of animal fertilizer available at a farm per hectar. [kg/ha]. More...
 
double m_totalFUdemandBefore
 Farm's total demand for fodder. [fodder units] More...
 
double m_totalFUdemand
 Farm's total demand for fodder (it is covered by growing fodder crops and/or purchasing fodder and thus, at the end of a year it should not be positive). [fodder units] More...
 
double m_totalFUt
 Fodder from trade (has to be purchased). [fodder units]. More...
 
double m_totalFUgrown
 Fodder grown, i.e. obtained from growing fodder crops. [fodder units]. More...
 
double m_assigned
 Variable holding a value of area already reserved for certain crops at a farm. [0-100%]. More...
 
double m_totalN
 Total amount of fertilizer used at a farm. [kg]. More...
 
double m_totalNt
 Total amount of fertilizer purchased at a farm. [kg]. More...
 
double m_totalBIHerb
 Total amount of herbicides which is planned to be applied at a farm. Expressed as a Treatment frequency index (behandling indeks, BI in Danish). More...
 
double m_totalBIFi
 Total amount of fung- and insecticides which is planned to be applied at a farm. Expressed as a Treatment frequency index (behandling indeks, BI in Danish). More...
 
double m_totalBI
 Total amount of pesticides (sum of m_totalBIHerb and m_totalBIFi) which is planned to be applied at a farm. Expressed as a Treatment frequency index (behandling indeks, BI in Danish). More...
 
double m_totalGrooming
 Total grooming planned at a farm. More...
 
double m_totalHoeing
 Total hoeing planned at a farm. More...
 
double m_totalWeeding
 Total manual weeding planned at a farm. More...
 
double m_totalCosts
 Planned total costs of growing crops at a farm. [DKK]. More...
 
double m_totalIncome
 Planned total income from growing crops at a farm. [DKK]. More...
 
double m_totalProfit
 Planned total profit (= income - costs) at a farm. In case of animal farms costs of purchased fodder is subtracted from the profit. [DKK]. More...
 
double m_area_rot
 Area assigned to rotational crops. [ha]. More...
 
- Protected Attributes inherited from Farm
FarmManagerm_OurManager
 Pointer to the FarmManager. More...
 
LowPriority< FarmEvent * > m_queue
 
vector< LE * > m_fields
 
vector< TTypesOfVegetationm_rotation
 
vector< PermCropDatam_PermCrops
 
TTypesOfFarm m_farmtype
 
HunterList m_HuntersList
 A list of hunters allocated to this farm. More...
 
bool m_stockfarmer
 
int m_farm_num
 
int m_rotation_sync_index
 
int m_intensity
 
int m_farm_centroidx
 Farm's centroid, value x. Equal to the average of the x centroid values of all farm's fields. More...
 
int m_farm_centroidy
 Farm's centroid, value y. Equal to the average of the y centroid values of all farm's fields. More...
 
Carrots * m_carrots
 
BroadBeans * m_broadbeans
 
FodderGrass * m_foddergrass
 
CloverGrassGrazed1 * m_CGG1
 
CloverGrassGrazed2 * m_CGG2
 
FieldPeas * m_fieldpeas
 
FieldPeasSilage * m_fieldpeassilage
 
Fodderbeet * m_fodderbeet
 
Sugarbeet * m_sugarbeet
 
OFodderbeet * m_ofodderbeet
 
Maize * m_maize
 
MaizeSilage * m_maizesilage
 
OMaizeSilage * m_omaizesilage
 
OBarleyPeaCloverGrass * m_OBarleyPCG
 
OCarrots * m_ocarrots
 
OCloverGrassGrazed1 * m_OCGG1
 
OCloverGrassGrazed2 * m_OCGG2
 
OCloverGrassSilage1 * m_OCGS1
 
OFieldPeas * m_ofieldpeas
 
OFieldPeasSilage * m_ofieldpeassilage
 
OFirstYearDanger * m_ofirstyeardanger
 
OGrazingPigs * m_ograzingpigs
 
OrchardCrop * m_orchardcrop
 
Oats * m_oats
 
OOats * m_ooats
 
OPermanentGrassGrazed * m_opermgrassgrazed
 
OPotatoes * m_opotatoes
 
OSeedGrass1 * m_oseedgrass1
 
OSeedGrass2 * m_oseedgrass2
 
OSpringBarley * m_ospringbarley
 
OSpringBarleyExt * m_ospringbarleyext
 
OSpringBarleyPigs * m_ospringbarleypigs
 
OSBarleySilage * m_osbarleysilage
 
OTriticale * m_otriticale
 
OWinterBarley * m_owinterbarley
 
OWinterBarleyExt * m_owinterbarleyext
 
OWinterRape * m_owinterrape
 
OWinterRye * m_owinterrye
 
OWinterWheatUndersown * m_owinterwheatundersown
 
OWinterWheat * m_owinterwheat
 
OWinterWheatUndersownExt * m_owinterwheatundersownext
 
PermanentGrassGrazed * m_permgrassgrazed
 
PermanentGrassLowYield * m_permgrasslowyield
 
PermanentGrassTussocky * m_permgrasstussocky
 
PermanentSetAside * m_permanentsetaside
 
Potatoes * m_potatoes
 
PotatoesIndustry * m_potatoesindustry
 
SeedGrass1 * m_seedgrass1
 
SeedGrass2 * m_seedgrass2
 
SetAside * m_setaside
 
SpringBarley * m_springbarley
 
SpringBarleySpr * m_springbarleyspr
 
SpringBarleySKManagement * m_springbarleyskmanagement
 
SpringBarleyPTreatment * m_springbarleyptreatment
 
SpringBarleyCloverGrass * m_sbarleyclovergrass
 
SpringBarleySeed * m_springbarleyseed
 
SpringBarleySilage * m_springbarleysilage
 
SpringRape * m_springrape
 
Triticale * m_triticale
 
WinterBarley * m_winterbarley
 
WinterRape * m_winterrape
 
WinterRye * m_winterrye
 
WinterWheat * m_winterwheat
 
WWheatPControl * m_wwheatpcontrol
 
WWheatPToxicControl * m_wwheatptoxiccontrol
 
WWheatPTreatment * m_wwheatptreatment
 
AgroChemIndustryCereal * m_agrochemindustrycereal
 
WinterWheatStrigling * m_winterwheatstrigling
 
WinterWheatStriglingCulm * m_winterwheatstriglingculm
 
WinterWheatStriglingSingle * m_winterwheatstriglingsingle
 
SpringBarleyCloverGrassStrigling * m_springbarleyclovergrassstrigling
 
SpringBarleyStrigling * m_springbarleystrigling
 
SpringBarleyStriglingCulm * m_springbarleystriglingculm
 
SpringBarleyStriglingSingle * m_springbarleystriglingsingle
 
MaizeStrigling * m_maizestrigling
 
WinterRapeStrigling * m_winterrapestrigling
 
WinterRyeStrigling * m_winterryestrigling
 
WinterBarleyStrigling * m_winterbarleystrigling
 
FieldPeasStrigling * m_fieldpeasstrigling
 
SpringBarleyPeaCloverGrassStrigling * m_springbarleypeaclovergrassstrigling
 
YoungForestCrop * m_youngforest
 
NorwegianPotatoes * m_norwegianpotatoes
 
NorwegianOats * m_norwegianoats
 
NorwegianSpringBarley * m_norwegianspringbarley
 
PLWinterWheat * m_plwinterwheat
 
PLWinterRape * m_plwinterrape
 
PLWinterBarley * m_plwinterbarley
 
PLWinterTriticale * m_plwintertriticale
 
PLWinterRye * m_plwinterrye
 
PLSpringWheat * m_plspringwheat
 
PLSpringBarley * m_plspringbarley
 
PLMaize * m_plmaize
 
PLMaizeSilage * m_plmaizesilage
 
PLPotatoes * m_plpotatoes
 
PLBeet * m_plbeet
 
PLFodderLucerne1 * m_plfodderlucerne1
 
PLFodderLucerne2 * m_plfodderlucerne2
 
PLCarrots * m_plcarrots
 
PLSpringBarleySpr * m_plspringbarleyspr
 
PLWinterWheatLate * m_plwinterwheatlate
 
PLBeetSpr * m_plbeetspr
 
PLBeans * m_plbeans
 
NLBeet * m_nlbeet
 
NLCarrots * m_nlcarrots
 
NLMaize * m_nlmaize
 
NLPotatoes * m_nlpotatoes
 
NLSpringBarley * m_nlspringbarley
 
NLWinterWheat * m_nlwinterwheat
 
NLCabbage * m_nlcabbage
 
NLTulips * m_nltulips
 
NLGrassGrazed1 * m_nlgrassgrazed1
 
NLGrassGrazed1Spring * m_nlgrassgrazed1spring
 
NLGrassGrazed2 * m_nlgrassgrazed2
 
NLGrassGrazedLast * m_nlgrassgrazedlast
 
NLPermanentGrassGrazed * m_nlpermanentgrassgrazed
 
NLBeetSpring * m_nlbeetspring
 
NLCarrotsSpring * m_nlcarrotsspring
 
NLMaizeSpring * m_nlmaizespring
 
NLPotatoesSpring * m_nlpotatoesspring
 
NLSpringBarleySpring * m_nlspringbarleyspring
 
NLCabbageSpring * m_nlcabbagespring
 
NLCatchPeaCrop * m_nlcatchpeacrop
 
DummyCropPestTesting * m_dummycroppesttesting
 

Detailed Description

A farm that carries out crop, pesticide and fertilizer planning using simplified optimisation or other decision startegies.

Constructor & Destructor Documentation

◆ OptimisingFarm()

OptimisingFarm::OptimisingFarm ( FarmManager a_myfarmmanager,
int  a_No 
)

The constructor.

5153  : Farm(a_myfarmmanager)
5154 {
5155 
5156 
5157  m_farmtype = tof_OptimisingFarm; //this is almass farm type (and not the optimising farm type - see OptimisingFarm::Initialize)
5158  m_almass_no = a_No;
5159  force_deliberation = false;
5161 
5162  //assign goals - DEFAULT values. Later FarmManager assigns main goals again.
5164  //m_pest_goal = tofg_profit;
5165  //m_fert_goal = tofg_profit;
5166 
5167  //initialize the actual and expected values
5168  m_actual_profit=0;
5169  m_actual_income=0;
5170  m_actual_costs=0;
5172  m_exp_profit=0;
5173  m_exp_income=0;
5174  m_exp_costs=0;
5176 
5177  //initialize the dec. mode counters
5178  m_decision_mode_counters.resize(4);
5180 
5181  m_animals_numbers.resize(0);
5182  animals_no = 0;
5183 
5184 }
FarmManager * m_OurManager
Pointer to the FarmManager.
Definition: farm.h:935
Farm(FarmManager *a_manager)
Farm constructor - creates an instance of each possible crop type.
Definition: farm.cpp:1058
TTypesOfFarm m_farmtype
Definition: farm.h:940
double m_actual_aggregated_yield
Actual aggregated yield at a farm in a given year.
Definition: farm.h:2131
vector< int > m_decision_mode_counters
Vector with counters for each decision mode. 0 - imitation, 1 - social comparison,...
Definition: farm.h:2114
double m_actual_profit
An actual profit realised at a farm in a given year.
Definition: farm.h:2118
double m_actual_income
An actual income at a farm in a given year.
Definition: farm.h:2122
double m_exp_costs
Expected costs at a farm in a given year.
Definition: farm.h:2128
int m_almass_no
Farm's almass number.
Definition: farm.h:2220
TTypeOfFarmerGoal m_main_goal
Farmer's main goal (determined by a farmer's type) .
Definition: farm.h:2103
double m_exp_profit
An expected farm's profit for a given year.
Definition: farm.h:2120
double m_exp_income
An expected farm's income at a farm in a given year.
Definition: farm.h:2124
vector< double > m_animals_numbers
Vector for storing numbers of animals at a farm in previous years (3).
Definition: farm.h:2150
double m_actual_costs
Actual costs at a farm in a given year.
Definition: farm.h:2126
int animals_no
Holds the number of animals in a farm at a particular day in a year (depends on a species).
Definition: farm.h:2154
OptimisingFarm * m_previously_imitated_neighbour
The neighbouring farmer whose crops might be copied in imitation and social comparison decision modes...
Definition: farm.h:2147
bool force_deliberation
If set to true, a farm must use deliberation as a decision strategy.
Definition: farm.h:2152
void Initialize(FarmManager *a_pfm)
Assigns to each farm its farm type, farm size, farm's real ID number, and soil type....
Definition: farm.cpp:5187
@ tofg_profit
Definition: farm.h:436
@ tof_OptimisingFarm
Definition: farm.h:273

References animals_no, force_deliberation, Initialize(), m_actual_aggregated_yield, m_actual_costs, m_actual_income, m_actual_profit, m_almass_no, m_animals_numbers, m_decision_mode_counters, m_exp_costs, m_exp_income, m_exp_profit, Farm::m_farmtype, m_main_goal, Farm::m_OurManager, m_previously_imitated_neighbour, tof_OptimisingFarm, and tofg_profit.

◆ ~OptimisingFarm()

virtual OptimisingFarm::~OptimisingFarm ( )
inlinevirtual
2033 { ; }

Member Function Documentation

◆ ActualProfit()

void OptimisingFarm::ActualProfit ( )

Function that determines actual crop yields and profit in a given year.

The function calculates actual yields, income, costs, profits etc. for a given farm in a previous year by accounting for crops grown at its fields. Determines farmer's need satisfaction level (m_need_satisfaction_level) which depends on farmer's actual results relative to the expected ones; the values compared depend on a farmer type, profit maximizer and environmentalist look at profit, yield maximizer looks at aggregated yield. The function also accounts for the pesticide and fertilizer usage in order to obtain aggregate results. The function is used only in ALMaSS crop set mode.

8806  {
8814  vector<TTypesOfVegetation> veg_type;
8815  //vector<double>profits; //profit from each field
8816  //profits.resize(m_fields.size());
8817 
8818  double priceNt = cfg_Price_Nt.value();
8819 
8820  //for energy maize impacts on wildlife
8821  bool emaize=false;
8822 
8823  //exp. agg. yield - for now it is not necessary to do this every year since the fields size is constant, but later it might change!
8824  m_exp_aggregated_yield = (double)m_fields.size(); //cause each field is expected to give 100% = 1. Except the fields with a crop with exp yield = 0.
8825 
8826  //go through all farm's field:
8827  for(int i=0; i<(int)m_fields.size(); i++){
8828 
8829  CropActualValues crop_data;
8830  TTypesOfVegetation crop;
8831  double biomass=0; double area=0; double yield_loss_pest=0; double no_herb_app=0; double no_fi_app=0;
8832  double unit_loss_herb=0; double unit_loss_fi=0; //to determine or take from field's data
8833  double yield_ha=0; double income_ha=0; double income=0; double costs_ha=0; double costs=0; double profit_ha=0; double profit=0; //to determine
8834  double yield_exp=0; double yield_ratio=0; double income_exp=0; double costs_exp=0; double profit_exp=0; //to account for - it was already calculated per crop in the determine GM function
8835  double sellingPrice=0; double priceHerb=0; double priceFi=0; double priceLM=0; double priceH=0; double priceW=0; double priceG=0; double subsidy=0; //economic data - need to be given as input;
8836  double no_missed_herb_app, no_missed_fi_app = 0; //no_missed - how many applications of herb/fi were missed
8837  double fert_applied=0; double fert_opt=0; double fert_trade=0; double beta1=0; double beta2=0; double alfaH=0; double alfaFI=0;
8838  double yield_factor = 0; //this serves both as biomass-to-yield factor and day degrees-to-yield factor - they are saved in one input table (a single crop has just one of these factors!)
8839  VegElement * pf = dynamic_cast<VegElement*>(m_fields[i]);
8840 
8841  int cropDataStorage_index=-1; //initialize
8842 
8843  if(pf->Get_taken(1)){ //there is a crop at position one - so account for this crop; otherwise go to position 0
8844  crop_data = pf->Get_CropDataStorage(1);
8845  cropDataStorage_index = 1;
8846  }
8847  else{
8848  crop_data = pf->Get_CropDataStorage(0);
8849  cropDataStorage_index = 0;
8850  if(crop_data.taken==false){//error
8851  g_msg->Warn( WARN_BUG, "OptimisingFarm::ActualProfit(): There is no crop data in the fields m_CropDataStorage", "" );
8852  exit( 1 );
8853  }
8854  }
8855 
8856  crop = crop_data.tov_type;
8857 
8858  //for energy maize impacts on wildlife
8859  if (crop==tov_Maize) emaize = true;
8860  //
8861 
8862  bool do_accounting = true;
8863  if(cropDataStorage_index==0){ //could be this crop was not harvested yet
8864  bool harvested = crop_data.harvested;
8867  && !harvested){
8868  //this is a crop that shoud be harvested, but so far it wasn't - so do not account for this crop yet! - just skip this field in accounting
8869  do_accounting = false;
8870  }
8871  }
8872 
8873  if(do_accounting){
8874  area = crop_data.area * 0.0001; //change the units from sq. meters to ha!
8875 
8876  if(crop==tov_SeedGrass1 || crop==tov_SeedGrass2){ //alfaherb is more than 100! - so problem with negative yield
8877  double betaH = crop_parameter(crop, "BetaHerb");
8878  alfaFI = crop_parameter(crop, "AlfaFi");
8879  unit_loss_herb = betaH/100/2;
8880  unit_loss_fi = alfaFI/100;
8881  }
8882  else{
8883  alfaH = crop_parameter(crop, "AlfaHerb");
8884  alfaFI = crop_parameter(crop, "AlfaFi");
8885  unit_loss_herb = alfaH/100; //yield loss per unit of herb application, = max yield loss/optBI = betaH/optBI = alfa. (and /100).
8886  unit_loss_fi = alfaFI/100; //yield loss per unit of fung-insecticide application
8887  }
8888 
8889  //draw random numbers to modify the pest related yield loss
8890  //method from: http://stackoverflow.com/questions/9651024/using-stdtr1normal-distribution-in-qt
8891  std::random_device rd;
8892  std::normal_distribution<double> dist(1, 0.2);
8893  std::mt19937 engine(rd());
8894  double r_number_1 = dist(engine);
8895  double r_number_2 = dist(engine);
8896 
8897 
8898  //determine the pest related yield loss
8899  no_missed_herb_app = crop_data.missed_herb_app;
8900  no_missed_fi_app = crop_data.missed_fi_app;
8901  yield_loss_pest = no_missed_herb_app * unit_loss_herb * r_number_1 + no_missed_fi_app * unit_loss_fi * r_number_2; //total yield loss due to missed pesticide applications
8902 
8903  //determine the yield
8904  biomass = crop_data.biomass_at_harvest;
8905  yield_factor = m_OurManager->pm_data->Get_biomass_factor(tov_Undefined * m_soilType + crop); //crop is tov - integer
8906 
8907  fert_applied = findCropByName_almass (crop)->m_n;
8908  fert_opt = findCropByName_almass (crop)->m_optimalN;
8909  fert_trade = findCropByName_almass (crop)->m_nt;
8910 
8911  int index = tov_Undefined * m_soilType + crop;
8912  beta1=m_OurManager->pm_data->Get_beta1(index);
8913  beta2=m_OurManager->pm_data->Get_beta2(index);
8914 
8915  double dd=m_OurManager->GetDD();
8916 
8917  yield_ha = (biomass==-1)? dd : biomass; //if biomass=-1 this crop is not harvested - use daydegress to estimate the yield
8918  yield_ha *= yield_factor; //multiply by the factor to convert biomass to yield - works both for harvested and not harvested crops.
8919  if(fert_opt!=0){
8920  yield_ha -= (1 - fert_applied/fert_opt) * (beta1 * fert_opt + beta2 * fert_opt*fert_opt); //subtract the amount which depends on the applied ferilizer - if the applied=optimal, then amount subtracted=0. The expression in brackets - with betas - corresponds to the max yield loss-when fert=0.
8921  }
8922  yield_ha *= (1-yield_loss_pest); //finally account for the yield loss due to pests
8923 
8924  //get other numbers for economic calculations
8925  sellingPrice = m_OurManager->pm_data->Get_sellingPrice(tov_Undefined*tos_Foobar*m_farmType + tov_Undefined*m_soilType + crop); //always tov_Undefined because this funtion is called ONLY in almass crop mode!
8926  priceFi = crop_parameter(crop, "PriceFi");
8927  priceHerb = crop_parameter(crop, "PriceHerb");
8928  priceG = crop_parameter(crop, "PriceG");
8929  priceH = crop_parameter(crop, "PriceH");
8930  priceW = crop_parameter(crop, "PriceW");
8931  priceLM = crop_parameter(crop, "PriceLM");
8932  subsidy =crop_parameter(crop, "Subsidy");
8933 
8934  double grooming = findCropByName_almass (crop)->m_grooming;
8935  double hoeing = findCropByName_almass (crop)->m_hoeing;
8936  double weeding = findCropByName_almass (crop)->m_weeding;
8937 
8938  no_herb_app = crop_data.no_herb_app;
8939  no_fi_app = crop_data.no_fi_app;
8940 
8941  //special case for potatoes and fodder beet
8942  if(crop==tov_Potatoes || crop==tov_PotatoesIndustry){
8943  no_herb_app = 1.41; //need to be consistent with numbers in the fix BI function!
8944  no_fi_app = 9.28;
8945  }
8946  if(crop==tov_FodderBeet){
8947  no_herb_app = 2.28; //need to be consistent with numbers in the fix BI function!
8948  }
8949 
8950  //saving the amount of pesticides and fertilizer
8951  if(g_date->GetYearNumber()>9){ //do it for the first time in year 10 ->only then we account for new dec.- modes
8952  for(int c=0; c<m_OurManager->pm_data->Get_noCrops(); c++){
8953  if(m_OurManager->Get_crops_summary_BIs_tov(c) == crop){
8954  m_OurManager->Set_crops_summary_BIs_herb(c, no_herb_app * area);
8955  m_OurManager->Set_crops_summary_BIs_fi(c, no_fi_app * area);
8956  m_OurManager->Set_crops_summary_BIs(c, (no_fi_app+no_herb_app) * area);
8957  m_OurManager->Set_crops_fertilizer(c, fert_applied * area);
8958  m_OurManager->Set_crops_fertilizer_trade(c, fert_trade * area);
8959  break;
8960  }
8961  }
8962  }
8963 
8964 
8965  //GET THE ACTUAL FIGURES:
8966  //1. determine the actual income from this crop: use selling price also for fodder crops! they do not add to income, just diminish the costs of fodder...hm
8967  income_ha = yield_ha * sellingPrice + subsidy;
8968  income = income_ha * area; //total income from this crop
8969 
8970  //2. account for the costs incurred for this crop
8971  costs_ha = no_herb_app*priceHerb + no_fi_app*priceFi + grooming*priceG + hoeing*priceH + weeding*priceW + fert_trade*priceNt+ priceLM;
8972  costs = costs_ha * area;
8973 
8974  //3. determine the actual profit
8975  profit_ha = income_ha - costs_ha;
8976  profit = profit_ha * area;
8977 
8978  //4. determine what part of the expected yield you actually got from this crop - but do this by ha! here there are only crops that were grown this year - because we go through the list of fields
8979  yield_exp = findCropByName_almass (crop)->m_resp;
8980  if(yield_exp!=0){
8981  yield_ratio = yield_ha/yield_exp; // must be min. 0, can be > than 1.
8982  }
8983  else{
8984  m_exp_aggregated_yield -=1; //this crop wasn't expected to yield anything, so exclude it from the sum of expected yields
8985  }
8986 
8987  //add actual figures for this crop to the totals at a farm this year
8988  m_actual_income += income;
8989  m_actual_costs += costs;
8990  m_actual_profit += profit;
8991  m_actual_aggregated_yield += yield_ratio;
8992 
8993 
8994  //add expected figures for this crop to the totals at a farm this year
8995  //get the expected values! use the actual area - otherwise a comparison doesn't make sense!
8996 
8997  //to determine the expected income use last year's price
8998  double resp = findCropByName_almass (crop)->m_resp;
8999  double totalLoss = findCropByName_almass (crop)->m_totalLoss;
9000  double sellingPrice_lastyr = m_OurManager->pm_data->Get_sellingPrice_lastyr(tov_Undefined*tos_Foobar*m_farmType + tov_Undefined*m_soilType + crop); //always tov_Undefined because this funtion is called ONLY in almass crop mode!
9001 
9003  bool fodder = m_OurManager->pm_data->Get_fodder(index1);
9004  if (fodder) income_exp = subsidy;
9005  else income_exp = (sellingPrice_lastyr*resp*(1-totalLoss/100)+subsidy)*area;
9006 
9007  costs_exp = findCropByName_almass (crop)->m_costs_ha *area;
9008  profit_exp = income_exp - costs_exp;
9009 
9010  m_exp_income += income_exp; //add income expected from this crop to the total expected income
9011  m_exp_costs += costs_exp;
9012  m_exp_profit += profit_exp;
9013 
9014  //clean data in this field's struct: remove the data that you just accounted for
9015  pf->Clean_CropDataStorage(cropDataStorage_index);
9016  }
9017  else{//there was no accounting done, print the crop and year in which this happened
9018  #ifdef _DEBUG
9019  g_msg->Warn("OptimisingFarm::ActualProfit(): There was no accounting for tov: ", crop);
9020  //g_msg->Warn("Farm Number: ",GetFarmNumber());
9021  g_msg->Warn("Year Number: ",g_date->GetYearNumber());
9022  #endif
9023  }
9024 
9025  //send the info on this field's crop for the landscape total crop areas accounting
9026  //first find the right index in m_cropTotals:
9027  int index_for_croptotals=0;
9029  for(int k = 0; k<size; k++){
9031  if(crop_type == crop){
9032  index_for_croptotals = k;
9033  break;
9034  }
9035  }
9036  //then add the area of this field to the right element of m_cropTotals; change the units from sq meters to ha.
9037  m_OurManager->Add_to_cropTotals(index_for_croptotals, m_fields[i]->GetArea() * 0.0001); //yearly totals
9038  if(g_date->GetYearNumber()>20){ //do it for the first time in year 10 ->only then we account for new dec.- modes//for wildlife runs - only since year 20 when emaize appears, but here in year 20 we only account for year 19...that's why it has to be '>20'
9039  m_OurManager->Set_cropTotals_sum(index_for_croptotals, m_fields[i]->GetArea() * 0.0001);
9040  if(m_farmType == toof_Plant){
9041  m_OurManager->Set_cropTotals_plant_sum(index_for_croptotals, m_fields[i]->GetArea() * 0.0001);
9042  }
9043  else if(m_farmType == toof_Pig){
9044  m_OurManager->Set_cropTotals_pig_sum(index_for_croptotals, m_fields[i]->GetArea() * 0.0001);
9045  }
9046  else if(m_farmType == toof_Cattle){
9047  m_OurManager->Set_cropTotals_cattle_sum(index_for_croptotals, m_fields[i]->GetArea() * 0.0001);
9048  }
9049  else if(m_farmType == toof_Other){
9050  m_OurManager->Set_cropTotals_other_sum(index_for_croptotals, m_fields[i]->GetArea() * 0.0001);
9051  }
9052  }
9053 
9054  //then add also to farm type specific crop totals
9055 
9056 
9057 
9058  }//for: going through m_fields
9059 
9060 
9061  //print the expected and actual values
9062  ofstream ofile ("Economic_figures.txt", ios::app);
9063  ofile << "farm_no: " << m_almass_no << '\t' << "year_no " << g_date->GetYearNumber() << endl;
9064  ofile << "Expected: " << '\t' <<"Income " << m_exp_income << "\tCosts "<< m_exp_costs << "\tProfit " << m_exp_profit<< "\tAgg.yield " << m_exp_aggregated_yield;
9065  ofile << endl;
9066  ofile << "Actual: " << '\t' << "Income " << m_actual_income << "\tCosts "<< m_actual_costs << "\tProfit " << m_actual_profit<< "\tAgg.yield " << m_actual_aggregated_yield;
9067  ofile << endl <<endl;
9068  ofile.close();
9069 
9070 
9071  //save the economic figures for this year (or rather past - we account for things happen in the year before the current March 1st, xxxx)
9074  m_previous_costs.push_back(m_actual_costs);
9076 
9077 
9078  double min_need_satisfaction1 = cfg_Min_need_satisfaction1.value();
9079  double min_need_satisfaction2 = cfg_Min_need_satisfaction2.value();
9080  if(cfg_OnlyDeliberation.value()){ //then everybody deliberates (and: min cert is set to 0 when config var OnlyDeliberation is set to true)
9081  min_need_satisfaction1 = 100;
9082  min_need_satisfaction2 = 100;
9083  }
9084 
9086  if(m_exp_profit>0){
9087  if(m_actual_profit >= min_need_satisfaction1*m_exp_profit){
9089  }
9090  else{
9092  }
9093  }
9094  else if(m_exp_profit<0){
9095  if(m_actual_profit >= (2 - min_need_satisfaction1) * m_exp_profit){ //e.g. EP=-1000, AP=-1100 -> ok for MNS<=0.9.
9097  }
9098  else{
9100  }
9101  }
9102  else{ //exp profit = 0
9103  m_need_satisfaction_level = (m_actual_profit >0)? 1 : 0; //need to deal with this case - not very likely to happen
9104  }
9105  }
9106  else if (m_main_goal == tofg_yield){
9107  m_need_satisfaction_level = (m_actual_aggregated_yield >= m_exp_aggregated_yield * min_need_satisfaction2)? 1 : 0 ;
9108  }
9109 
9110  m_previous_satisfaction_levels.push_back(m_need_satisfaction_level); //add it to the list of satisfaction levels from last 5 years
9111  if(m_previous_satisfaction_levels.size()>5){ // it's been more than 5 years since the first accoutning, so...
9112  m_previous_satisfaction_levels.erase(m_previous_satisfaction_levels.begin()); //remove the first element: satisfaction level 6 years ago
9113  }
9114 
9115  //for energy maize impact on wildlife - January 2014
9116  if(cfg_MaizeEnergy.value()){
9117  double threshold = cfg_AnimalsThreshold.value();
9118  double sum = 0;
9119  for(int i=0; i<m_animals_numbers.size(); i++){
9120  sum += m_animals_numbers[i];
9121  }
9122  double avrg_animals_no = 0;
9123  if(m_animals_numbers.size()>0){
9124  avrg_animals_no = sum/m_animals_numbers.size();
9125  }
9126 
9127  if(emaize && animals_no < threshold * avrg_animals_no && m_animals_numbers.size()>2){ //three conditions: 1. you actually have grown energy maize
9128  // 2. the animal numbers have decreased below the acceptable level 3. you have data on animal numbers from min. 3 years
9129  //then set the rotation max. for energy maize to zero and force deliberation to stop growing energy maize
9130  CropOptimised *em = findCropByName_almass ("Maize");
9131  em->m_rotationMax = 0;
9132  force_deliberation = true;
9133  }
9134  m_animals_numbers.push_back(animals_no);
9135  if(m_animals_numbers.size() > 3){ //have data for more than 3 years now
9136  m_animals_numbers.erase(m_animals_numbers.begin()); //remove the oldest data - first element
9137  }
9138 
9139  //force optimisation when energy maize price changed by more than a given %
9142  if(abs(EMPrice_current - EMPrice_lastyr) > EMPrice_lastyr * cfg_PriceChangeThreshold.value()){
9143  force_deliberation = true;
9144  }
9145  }
9146  //
9147 
9148  //and restart the actual and expected values - for next year
9149  m_exp_income = 0;
9150  m_exp_costs = 0;
9151  m_exp_profit = 0;
9152  //exp agg yield is determined at the begininng of this function;
9153  m_actual_income = 0;
9154  m_actual_costs = 0;
9155  m_actual_profit = 0;
9157 
9158 }
class Calendar * g_date
Definition: calendar.cpp:38
int GetYearNumber(void)
Definition: calendar.h:68
bool value(void)
Definition: configurator.h:135
double value(void)
Definition: configurator.h:118
A class for storing all parameters and results of crop optimisation.
Definition: farm.h:1634
double m_grooming
Value of mechanical weed control for a crop - grooming [DKK/ha].
Definition: farm.h:1673
double m_optimalN
Optimal amount of fertilizer per ha of a crop supposing ferilizer price equals zero [kg N/ha]....
Definition: farm.h:1660
double m_hoeing
Value of mechanical weed control for a crop - hoeing [DKK/ha].
Definition: farm.h:1675
double m_n
Total amount of fertilizer applied per ha of a crop [kg N/ha].
Definition: farm.h:1656
double m_nt
Amount of purchased (and applied) fertilizer per ha of a crop [kg N/ha].
Definition: farm.h:1658
double m_rotationMax
Maximum area in percent of farm's arable area for a given crop (depends on a farm size,...
Definition: farm.h:1650
double m_totalLoss
Summary value of the yield loss due to the limited use of herbicides and fung- and insecticides [%].
Definition: farm.h:1683
TTypesOfVegetation m_cropType_almass
Type/name of a crop (ALMaSS crops).
Definition: farm.h:1646
double m_resp
Response - yield of a crop per ha [hkg/ha].
Definition: farm.h:1665
double m_weeding
Value of mechanical weed control for a crop - manual weeding [DKK/ha].
Definition: farm.h:1677
double m_costs_ha
Costs of growing 1 ha of a crop. Include costs of labour and machine (constant), pesticides (herbicid...
Definition: farm.h:1685
int Get_noCrops()
Definition: farm.h:669
double Get_beta2(int i)
Definition: farm.h:629
int Get_cropTypes_almass_size()
Definition: farm.h:664
TTypesOfVegetation Get_cropTypes_almass(int i)
Definition: farm.h:663
double Get_biomass_factor(int i)
Definition: farm.h:660
double Get_sellingPrice(int i)
Definition: farm.h:648
bool Get_fodder(int i)
Definition: farm.h:643
double Get_beta1(int i)
Definition: farm.h:627
double Get_sellingPrice_lastyr(int i)
Definition: farm.h:650
vector< LE * > m_fields
Definition: farm.h:937
int GetArea(void)
Returns the area of arable fields owned by that farm.
Definition: farm.cpp:1331
void Add_to_cropTotals(int i, double value)
Definition: farm.h:1838
void Set_crops_fertilizer_trade(int i, double fert_trade)
Definition: farm.h:1864
void Set_cropTotals_other_sum(int i, double crop_area)
Definition: farm.h:1861
void Set_cropTotals_sum(int i, double crop_area)
Definition: farm.h:1857
void Set_cropTotals_pig_sum(int i, double crop_area)
Definition: farm.h:1859
DataForOptimisation * pm_data
Pointer to the DataForOptimisation.
Definition: farm.h:1876
void Set_cropTotals_plant_sum(int i, double crop_area)
Definition: farm.h:1858
void Set_crops_summary_BIs(int i, double BI)
Definition: farm.h:1856
void Set_crops_summary_BIs_herb(int i, double BIherb)
Definition: farm.h:1854
void Set_crops_summary_BIs_fi(int i, double BIfi)
Definition: farm.h:1855
double GetDD(void)
Returnes day degrees for the period March 1st - November 1st. Used for determining yields of crops th...
Definition: farm.h:1835
void Set_cropTotals_cattle_sum(int i, double crop_area)
Definition: farm.h:1860
TTypesOfVegetation Get_crops_summary_BIs_tov(int i)
Definition: farm.h:1853
void Set_crops_fertilizer(int i, double fert)
Definition: farm.h:1863
void Warn(MapErrorState a_level, std::string a_msg1, std::string a_msg2)
Definition: maperrormsg.cpp:59
double crop_parameter(int index, string par_name)
Reads in crop parameters that do NOT vary with any farm level parameters.
Definition: farm.cpp:7756
vector< double > m_previous_profits
Vector of profits from previous years.
Definition: farm.h:2137
double m_need_satisfaction_level
Farmer's actual satisfaction level.
Definition: farm.h:2110
TTypesOfOptFarms m_farmType
Farm's type (cattle, pig, plant, other).
Definition: farm.h:2210
vector< double > m_previous_aggregated_yields
Vector of aggregated yields from previous years.
Definition: farm.h:2143
CropOptimised * findCropByName_almass(string crop_name)
Returns a pointer to almass crop whose name is specified as the argument (ALMaSS crops mode).
Definition: farm.cpp:7770
double m_exp_aggregated_yield
Expected aggregated yield at a farm in a given year.
Definition: farm.h:2134
vector< double > m_previous_satisfaction_levels
Vector of satisfaction levels in five previous years.
Definition: farm.h:2145
TTypesOfSoils m_soilType
Farm's soil type (sandy, clay, other).
Definition: farm.h:2212
vector< double > m_previous_incomes
Vector of incomes from previous years.
Definition: farm.h:2139
vector< double > m_previous_costs
Vector of costs from previous years.
Definition: farm.h:2141
Definition: elements.h:568
CropActualValues Get_CropDataStorage(int index)
Definition: elements.h:663
void Clean_CropDataStorage(int index)
Definition: elements.cpp:2129
bool Get_taken(int index)
Definition: elements.h:638
CfgFloat cfg_AnimalsThreshold("ANIMALS_THRESHOLD", CFG_CUSTOM, 0)
This parameter specifies the proportion of average number of animals on a farm for previous 3 years,...
CfgFloat cfg_Min_need_satisfaction2("MIN_NEED_SATISFACTION_TWO", CFG_CUSTOM, 100)
A parameter setting the minimum satisfaction level for yield.
CfgFloat cfg_Min_need_satisfaction1("MIN_NEED_SATISFACTION_ONE", CFG_CUSTOM, 100)
A parameter setting the minimum satisfaction level for profit.
CfgBool cfg_MaizeEnergy("MAIZE_ENERGY", CFG_CUSTOM, false)
If set to true, the energy maize crop is included in the simulation.
CfgBool cfg_OnlyDeliberation("ONLY_DELIBERATION", CFG_CUSTOM, true)
If set to yes, the only decision mode/startegy the farmers can use is deliberation (i....
CfgFloat cfg_PriceChangeThreshold("PRICE_CHANGE_THRESHOLD", CFG_CUSTOM, 0.2)
This parameter specifies the relative difference in energy maize price which causes a farmer to delib...
CfgFloat cfg_Price_Nt("PRICE_NT", CFG_CUSTOM, 1.93)
Price of fertilizer. [DKK/kg].
@ tofg_environment
Definition: farm.h:438
@ tofg_yield
Definition: farm.h:437
@ toof_Other
Definition: farm.h:279
@ toof_Cattle
Definition: farm.h:280
@ toof_Plant
Definition: farm.h:281
@ toof_Pig
Definition: farm.h:282
@ tos_Foobar
Definition: farm.h:290
class MapErrorMsg * g_msg
This pointer provides access the to the internal ALMaSS error message system.
Definition: maperrormsg.cpp:41
@ WARN_BUG
Definition: maperrormsg.h:34
Struct for storing actual data on crop type, area of a field it is grown in, biomass at harvest,...
Definition: elements.h:555
double biomass_at_harvest
Definition: elements.h:558
TTypesOfVegetation tov_type
Definition: elements.h:557
double area
Definition: elements.h:560
int missed_herb_app
Definition: elements.h:562
bool harvested
Definition: elements.h:559
int no_herb_app
Definition: elements.h:561
int missed_fi_app
Definition: elements.h:564
bool taken
Definition: elements.h:556
int no_fi_app
Definition: elements.h:563
TTypesOfVegetation
Definition: tov_declaration.h:30
@ tov_PermanentGrassGrazed
Definition: tov_declaration.h:49
@ tov_FodderGrass
Definition: tov_declaration.h:62
@ tov_SeedGrass1
Definition: tov_declaration.h:50
@ tov_CloverGrassGrazed2
Definition: tov_declaration.h:33
@ tov_PotatoesIndustry
Definition: tov_declaration.h:50
@ tov_PermanentGrassTussocky
Definition: tov_declaration.h:49
@ tov_SpringBarleySilage
Definition: tov_declaration.h:52
@ tov_SeedGrass2
Definition: tov_declaration.h:50
@ tov_Undefined
Definition: tov_declaration.h:114
@ tov_PermanentGrassLowYield
Definition: tov_declaration.h:63
@ tov_CloverGrassGrazed1
Definition: tov_declaration.h:32
@ tov_Maize
Definition: tov_declaration.h:36
@ tov_Potatoes
Definition: tov_declaration.h:50
@ tov_FodderBeet
Definition: tov_declaration.h:35
@ tov_YoungForest
Definition: tov_declaration.h:60
@ tov_OrchardCrop
Definition: tov_declaration.h:65

References FarmManager::Add_to_cropTotals(), animals_no, CropActualValues::area, CropActualValues::biomass_at_harvest, cfg_AnimalsThreshold, cfg_MaizeEnergy, cfg_Min_need_satisfaction1, cfg_Min_need_satisfaction2, cfg_OnlyDeliberation, cfg_Price_Nt, cfg_PriceChangeThreshold, VegElement::Clean_CropDataStorage(), crop_parameter(), findCropByName_almass(), force_deliberation, g_date, g_msg, DataForOptimisation::Get_beta1(), DataForOptimisation::Get_beta2(), DataForOptimisation::Get_biomass_factor(), VegElement::Get_CropDataStorage(), FarmManager::Get_crops_summary_BIs_tov(), DataForOptimisation::Get_cropTypes_almass(), DataForOptimisation::Get_cropTypes_almass_size(), DataForOptimisation::Get_fodder(), DataForOptimisation::Get_noCrops(), DataForOptimisation::Get_sellingPrice(), DataForOptimisation::Get_sellingPrice_lastyr(), VegElement::Get_taken(), Farm::GetArea(), FarmManager::GetDD(), Calendar::GetYearNumber(), CropActualValues::harvested, m_actual_aggregated_yield, m_actual_costs, m_actual_income, m_actual_profit, m_almass_no, m_animals_numbers, CropOptimised::m_costs_ha, CropOptimised::m_cropType_almass, m_exp_aggregated_yield, m_exp_costs, m_exp_income, m_exp_profit, m_farmType, Farm::m_fields, CropOptimised::m_grooming, CropOptimised::m_hoeing, m_main_goal, CropOptimised::m_n, m_need_satisfaction_level, CropOptimised::m_nt, CropOptimised::m_optimalN, Farm::m_OurManager, m_previous_aggregated_yields, m_previous_costs, m_previous_incomes, m_previous_profits, m_previous_satisfaction_levels, CropOptimised::m_resp, CropOptimised::m_rotationMax, m_soilType, CropOptimised::m_totalLoss, CropOptimised::m_weeding, CropActualValues::missed_fi_app, CropActualValues::missed_herb_app, CropActualValues::no_fi_app, CropActualValues::no_herb_app, FarmManager::pm_data, FarmManager::Set_crops_fertilizer(), FarmManager::Set_crops_fertilizer_trade(), FarmManager::Set_crops_summary_BIs(), FarmManager::Set_crops_summary_BIs_fi(), FarmManager::Set_crops_summary_BIs_herb(), FarmManager::Set_cropTotals_cattle_sum(), FarmManager::Set_cropTotals_other_sum(), FarmManager::Set_cropTotals_pig_sum(), FarmManager::Set_cropTotals_plant_sum(), FarmManager::Set_cropTotals_sum(), CropActualValues::taken, tofg_environment, tofg_profit, tofg_yield, toof_Cattle, toof_Other, toof_Pig, toof_Plant, tos_Foobar, tov_CloverGrassGrazed1, tov_CloverGrassGrazed2, tov_FodderBeet, tov_FodderGrass, tov_Maize, tov_OrchardCrop, tov_PermanentGrassGrazed, tov_PermanentGrassLowYield, tov_PermanentGrassTussocky, tov_Potatoes, tov_PotatoesIndustry, tov_SeedGrass1, tov_SeedGrass2, tov_SpringBarleySilage, CropActualValues::tov_type, tov_Undefined, tov_YoungForest, CfgFloat::value(), CfgBool::value(), MapErrorMsg::Warn(), and WARN_BUG.

Referenced by FarmManager::ActualProfit().

◆ assignFixed()

void OptimisingFarm::assignFixed ( )
protected

Adds areas of fixed crops to the variable m_assigned. For each fixed crop it saves its area under variable CropOptimised::m_areaPercent.

Function assigning to fixed crops their initial areas as percentages of a farm's total area. It determines the share of a farm (%) reserved for fixed crops - excluded from the optimisation - and saves it in a variable m_assigned.

6275  {
6276 
6280  m_assigned = 0;
6281  for (int i=0; i<(int)m_fixedCrops.size(); i++){//take only crops that are fixed
6282  double area = m_fixedCrops[i]->m_initialArea;
6283 
6284  if(!cfg_UseBedriftsmodelFarmAreas.value()){ //almass farm areas are in use, so scale the fixed crop area
6285  area *= m_area_scaling_factor;
6286  }
6287 
6288  double areaPercent= area/m_totalArea*100;
6289  m_fixedCrops[i]->m_areaPercent = areaPercent; //assign initial area in % for fixed crops
6290  m_assigned += areaPercent;//add areaPercent of a fixed crop to assigned
6291  }//now assigned is a number <0, 100> - excluded from the optimisation
6292 }
double m_area_scaling_factor
Factor used to scale areas of fixed crops and livestock numbers. Used to adjust these values to the f...
Definition: farm.h:2228
double m_totalArea
Total area of a farm. A sum of initial crop areas (if in bedriftsmodel, i.e. original farm optimizati...
Definition: farm.h:2224
double m_assigned
Variable holding a value of area already reserved for certain crops at a farm. [0-100%].
Definition: farm.h:2242
vector< CropOptimised * > m_fixedCrops
Vector of pointers to fixed crops.
Definition: farm.h:2194
CfgBool cfg_UseBedriftsmodelFarmAreas("USE_BEDRIFTSMODEL_FARM_AREAS", CFG_CUSTOM, false)
If set to true, the farm areas from the original farm optimisation model are used in the optimisation...

References cfg_UseBedriftsmodelFarmAreas, m_area_scaling_factor, m_assigned, m_fixedCrops, m_totalArea, and CfgBool::value().

Referenced by OptimiseFarm().

◆ Check_if_area_100()

void OptimisingFarm::Check_if_area_100 ( )
protected

Checks if the sum of crops' areaPercent is 100%.

Determines the sum of all crops' CropOptimised::m_areaPercent. If the sum is not equal to 100, it issues a warning in a "Check_if_area_is_100%.txt" file.

8060  {
8063  double area_to_check = 0.0;
8064  for(int i=0; i<(int)m_crops.size(); i++) {
8065  area_to_check += m_crops[i]->m_areaPercent;
8066  }
8067 
8068  if(area_to_check > 100.0001 || area_to_check < 99.999){ //issue a warning
8069  ofstream ofile("Check_if_area_is_100%.txt",ios::app);
8070  ofile << m_almass_no << '\t' << "Farms area is not equal to 100%. The sum of crops areaPercent is: " << area_to_check << endl;
8071  ofile.close();
8072  }
8073 }
vector< CropOptimised * > m_crops
Vector of pointers to all crops.
Definition: farm.h:2183

References m_almass_no, and m_crops.

Referenced by OptimiseFarm().

◆ Check_SG_and_CGG()

void OptimisingFarm::Check_SG_and_CGG ( )
protected

Modifies areas of SeedGrass1 and SeedGrass2, CloverGrassGrazed1 and CloverGrassGrazed2 to be even. Used only in ALMaSS crops mode (in Bedriftsmodel (original farm optimization model) crops mode this is taken care of in Translate_crops_to_almass()).

5877  {
5878 
5879  CropOptimised *CGG1 = findCropByName_almass("CloverGrassGrazed1");
5880  CropOptimised *CGG2 = findCropByName_almass("CloverGrassGrazed2");
5881  CropOptimised *GS1 = findCropByName_almass("SeedGrass1");
5882  CropOptimised *GS2 = findCropByName_almass("SeedGrass2");
5883 
5884  double CGG1area = CGG1->m_areaPercent;
5885  double CGG2area = CGG2->m_areaPercent;
5886  double GS1area = GS1->m_areaPercent;
5887  double GS2area = GS2->m_areaPercent;
5888  if(CGG1area!= CGG2area){ //even if this is a cattle farm - where CGG are fodder - it won't have any effect here since the areas are zero or at min, so there won't be any change.
5889  double area_sum = CGG1area + CGG2area;
5890  double CGG1min = CGG1->m_rotationMin; double CGG2min = CGG2->m_rotationMin;
5891  CGG1->m_areaPercent = area_sum/2; CGG2->m_areaPercent = area_sum/2;
5892  CGG1->m_areaVariable = area_sum/2 - CGG1min; CGG2->m_areaVariable = area_sum/2 - CGG2min;
5893  }
5894  if(GS1area!=GS2area){
5895  double area_sum = GS1area + GS2area;
5896  double GS1min = GS1->m_rotationMin; double GS2min = GS2->m_rotationMin;
5897  GS1->m_areaPercent = area_sum/2; GS2->m_areaPercent = area_sum/2;
5898  GS1->m_areaVariable = area_sum/2 - GS1min; GS2->m_areaVariable = area_sum/2 - GS2min;
5899  }
5900 }
double m_rotationMin
Minimum area in percent of farm's arable area for a given crop (depends on a farm size,...
Definition: farm.h:1652
double m_areaVariable
Area of a crop that can be changed when checking for restrictions (=m_areaPercent - m_rotationMin) [%...
Definition: farm.h:1697
double m_areaPercent
Area of a crop in percent of a farm's total area [%].
Definition: farm.h:1695

References findCropByName_almass(), CropOptimised::m_areaPercent, CropOptimised::m_areaVariable, and CropOptimised::m_rotationMin.

Referenced by checkRestrictions().

◆ checkRestrictions()

void OptimisingFarm::checkRestrictions ( )
protectedvirtual

Checks if the restrictions are fulfilled and corrects crops' areas if necessary.

Function checking if restrictions concerning crop rotations are fulfilled. If not, it corrects the crop areas in order to fulfill the restrictions. It starts with checking the restriction on winter crops rotation. Then it checks restriction on max winter crops' area. Finally, for cattle farms it checks the restriction on crop rotation.

The order of checking the first two restrictions does matter: in case the first restriction is not fullfilled, the first function always decreases winter wheat's area and only in a particular case increases area of winter rape. Thus, the total area of winter crops (->second restriction) most likely is decreased or, otherwise - unchanged by the function dealing with the first restriction. The second restriction, on max area of winter crops, does not allow to decrease area of winter rape; this, in certain cases, might result in suboptimal final result, but ensures that the first restriction is not violated. In the third restriction
(only in the version for cattle farms) in the Bedriftsmodel crop mode, winter wheat is removed from the list of crops which is used to fill up the gap after decreasing some of the restriction crops.

In the ALMaSS crops mode the third restriction (for cattle farms) is implemented in a simplified version, i.e. it is limited to changing only areas of crops that form the restriction. Additionally, in the ALMaSS crops mode there is a function which ensures that areas of both CloverGrassGrazed1 and CloverGrassGrazed2 as well as SeedGrass1 and SeedGrass2 are equal (since '1' and '2' are the same crops, but with different management in the first and next year they are grown).

Reimplemented in OptimisingCattleFarm, and OptimisingPigFarm.

6410  {
6429  //1st restriction: winter rotation
6430  if(!cfg_Areas_Based_on_Distribution.value()){ //if this is true, skip this restriction
6432  }
6433 
6434  //2nd restriction: max share of winter crops area
6435  checkWinterCrops();
6436 
6437  if (!cfg_OptimiseBedriftsmodelCrops.value()){ //just for almass crop mode: make sure cgg1 and cgg2, sgg1 and sgg2 - have equal areas. added 26.03.13 -function since 110613
6438  Check_SG_and_CGG();
6439  }
6440 }
virtual void checkWinterRotation1()
Checks if the restriction on a winter rotation is fulfilled.
Definition: farm.h:2330
virtual void checkWinterCrops()
Checks if the restriction on a max. share of winter crops is fulfilled.
Definition: farm.h:2332
void Check_SG_and_CGG()
Modifies areas of SeedGrass1 and SeedGrass2, CloverGrassGrazed1 and CloverGrassGrazed2 to be even....
Definition: farm.cpp:5877
CfgBool cfg_Areas_Based_on_Distribution("AREAS_BASED_ON_DISTRIBUTION", CFG_CUSTOM, false)
If set to true, crops are assigned area based on their gross margin proportion in the total GM for al...
CfgBool cfg_OptimiseBedriftsmodelCrops("OPTIMISE_BEDRIFTSMODEL_CROPS", CFG_CUSTOM, false)
If set to true, the original farm optimisation model's crop set is used in the farmer decision making...

References cfg_Areas_Based_on_Distribution, cfg_OptimiseBedriftsmodelCrops, Check_SG_and_CGG(), checkWinterCrops(), checkWinterRotation1(), and CfgBool::value().

Referenced by OptimisingPigFarm::checkRestrictions(), OptimisingCattleFarm::checkRestrictions(), and OptimiseFarm().

◆ checkWinterCrops()

virtual void OptimisingFarm::checkWinterCrops ( )
inlineprotectedvirtual

Checks if the restriction on a max. share of winter crops is fulfilled.

Reimplemented in NonAnimalFarm, and AnimalFarm.

2332 {};

Referenced by checkRestrictions().

◆ checkWinterRotation1()

virtual void OptimisingFarm::checkWinterRotation1 ( )
inlineprotectedvirtual

Checks if the restriction on a winter rotation is fulfilled.

Reimplemented in NonAnimalFarm, and AnimalFarm.

2330 {};

Referenced by checkRestrictions().

◆ ChooseDecisionMode()

void OptimisingFarm::ChooseDecisionMode ( )

Function determines which decision mode to use. The choice depends on the values of need satisfaction and uncertainty.

In the first year the function is called (8), it calls Find_neighbour_to_imitate. Every year it determines a farmer's certainty level. Depending on farmer's satisfaction and certainty levels it picks a decision mode: imitation if a farmer is uncertain, but satisfied; social comparison if a farmer is uncertain and not satisfied; repetition if a farmer is certain and satisifed; or deliberation if a farmer is certain, but not satisifed.

5478  {
5483  //pick a farmer to copy (imitation startegy)/ or compare with and possibly copy (social comparison strategy) if this is the first time this function is called: year 8
5484  if(g_date->GetYearNumber() == 8){
5486  }
5487 
5488  //1. get the values of parameters
5489  double min_certainty = cfg_Min_certainty.value();
5490  if(cfg_OnlyDeliberation.value()) min_certainty = 0;
5491 
5492  //2. determine the satisfaction level: already done in the ActualProfit()
5493 
5494  //3. determine the certainty level
5495  double sum_of_sat_levels=0;
5496  for(int i=0; i<5; i++){
5497  sum_of_sat_levels += m_previous_satisfaction_levels[i];
5498  }
5499  m_certainty_level = sum_of_sat_levels/5.0; // i.e. take 5 years into account
5500 
5501  //4. choose the decision mode
5502  //'if' for forcing deliberation:
5503  if(force_deliberation){ //do the same as when deliberation is chosen normally
5505  m_totalFUdemand=m_totalFUdemandBefore; //restart the fodder demand to the original value
5506  m_totalFUgrown = 0; //restart
5508  Make_almass_crops_vector(); //makes m_crops_almass
5509  Make_rotational_crops(); //makes new m_rotational_crops - based on m_crops_almass
5511  force_deliberation=false;
5512  }
5513  else{
5514  if(m_certainty_level < min_certainty){
5515  if(m_need_satisfaction_level == 1 ){ //IMITATION (high sat., low cert.)
5517  //now imitate:
5519  m_rotational_crops_copy = m_rotational_crops; //m_rotational_crops_copy is used for finding a crop for a given field - in Match_crop_to_field function.
5520  } //imitation over
5521 
5522  else{ //SOCIAL COMPARISON - similar to imitation, but includes comparison (low sat., low cert.)
5524  //compare yourself to the neighbour: this depends on your goal
5525  bool imitate=false;
5526  if(m_main_goal == tofg_profit){
5527  if(m_actual_profit < m_previously_imitated_neighbour->Get_actual_profit()){
5528  imitate=true;
5529  }
5530  }
5531  else if (m_main_goal == tofg_yield){
5532  if(m_actual_aggregated_yield < m_previously_imitated_neighbour->Get_actual_aggregated_yield()){
5533  imitate=true;
5534  }
5535  }
5536  else if (m_main_goal == tofg_environment) {
5537  if(m_actual_aggregated_yield < m_previously_imitated_neighbour->Get_actual_aggregated_yield() && m_actual_profit < m_previously_imitated_neighbour->Get_actual_profit()){//compare both
5538  imitate=true;
5539  }
5540  }
5541 
5542  if(imitate){
5544  }
5545  //else: just continue
5546  m_rotational_crops_copy = m_rotational_crops; //this happens for both cases - imitate or not
5547  } //social comparison over
5548  } //high uncertainty
5549 
5550  else{ //low uncertainty (= high certainty)
5551  int value_for_satisfaction = 1; //1 for a simulation with not only deliberation
5552  if(cfg_OnlyDeliberation.value()) value_for_satisfaction = 10; //10 - then everybody deliberates
5553  if(m_need_satisfaction_level == value_for_satisfaction){ //REPETITION (high sat., high cert.)
5555  //continue with the same set of crops - see line after else!
5556  }
5557  else{ //DELIBERATION - i.e. optimise to make a new m_rotational_crops (low sat., high cert.)
5559  m_totalFUdemand=m_totalFUdemandBefore; //restart the fodder demand to the original value
5560  m_totalFUgrown = 0; //restart
5562  Make_almass_crops_vector(); //makes m_crops_almass
5563  Make_rotational_crops(); //makes new m_rotational_crops - based on m_crops_almass
5564  }
5565  m_rotational_crops_copy = m_rotational_crops; //do this for both cases
5566  }
5567  }
5568 }
void Make_rotational_crops()
Creates a vector m_rotational_crops using the results of optimisation.
Definition: farm.cpp:8285
double m_totalFUgrown
Fodder grown, i.e. obtained from growing fodder crops. [fodder units].
Definition: farm.h:2240
void OptimiseFarm(int a_foobar)
Carries out the whole farm optimisation.
Definition: farm.cpp:5765
vector< AlmassCrop > Get_rotational_crops_visible()
Definition: farm.h:2052
OptimisingFarm * Find_neighbour_to_imitate()
Picks randomly a farmer to imitate/compare with. It chooses among neighbouring farmers with similar f...
Definition: farm.cpp:5380
double m_totalFUdemand
Farm's total demand for fodder (it is covered by growing fodder crops and/or purchasing fodder and th...
Definition: farm.h:2236
double m_totalFUdemandBefore
Farm's total demand for fodder. [fodder units]
Definition: farm.h:2234
vector< AlmassCrop > m_rotational_crops
Vector of structs with almass type crops with positive areas in % (result of optimisation): includes ...
Definition: farm.h:2202
double Get_actual_aggregated_yield()
Definition: farm.h:2054
void Make_almass_crops_vector()
Creates a vector storing crops with positive area. Used in ALMaSS crop mode.
Definition: farm.cpp:8269
vector< AlmassCrop > m_rotational_crops_copy
A copy of m_rotational_crops used when matching crops to fields.
Definition: farm.h:2204
double m_certainty_level
Farmer's certainty level.
Definition: farm.h:2112
double Get_actual_profit()
Definition: farm.h:2053
CfgFloat cfg_Min_certainty("MIN_CERTAINTY", CFG_CUSTOM, 0)
A parameter setting the minimum certainty level.

References cfg_Min_certainty, cfg_OnlyDeliberation, Find_neighbour_to_imitate(), force_deliberation, g_date, Get_actual_aggregated_yield(), Get_actual_profit(), Get_rotational_crops_visible(), Calendar::GetYearNumber(), m_certainty_level, m_decision_mode_counters, m_main_goal, m_need_satisfaction_level, m_previous_satisfaction_levels, m_previously_imitated_neighbour, m_rotational_crops, m_rotational_crops_copy, m_totalFUdemand, m_totalFUdemandBefore, m_totalFUgrown, Make_almass_crops_vector(), Make_rotational_crops(), OptimiseFarm(), tofg_environment, tofg_profit, tofg_yield, tov_Undefined, CfgFloat::value(), and CfgBool::value().

Referenced by FarmManager::ChooseDecisionMode_for_farms().

◆ createCropsLists()

void OptimisingFarm::createCropsLists ( int  a_foobar)
protectedvirtual

Creates lists of crops.

Reimplemented in AnimalFarm.

5570  {
5571  createVariableCrops(a_foobar);
5572 }
void createVariableCrops(int a_foobar)
Creates a list of pointers to all variable crops included in the optimisation and a list of pointers ...
Definition: farm.cpp:5579

References createVariableCrops().

Referenced by Init().

◆ createVariableCrops()

void OptimisingFarm::createVariableCrops ( int  a_foobar)
protected

Creates a list of pointers to all variable crops included in the optimisation and a list of pointers to fixed crops.

Creates two vectors: vector of pointers to fixed crops and a vector of structs containing variable crops.

5579  {
5582  int n = (int)m_crops.size();
5583  for (int i=0; i < n; ++i) {
5584  int crop_type=(cfg_OptimiseBedriftsmodelCrops.value())? (int)m_crops[i]->m_cropType : (int)m_crops[i]->m_cropType_almass;
5585  int index=a_foobar*m_farmType + crop_type;
5586  if (m_OurManager->pm_data->Get_fixed(index)){ //if the crop is fixed, attach it to the list fixedCrops
5587  m_fixedCrops.push_back(m_crops[i]);
5588  }
5589  else{
5590  CropSort cs = {0., m_crops[i]}; //an object with a key and a pointer to crop
5591  m_variableCrops.push_back(cs);
5592  }
5593  }
5594 }
bool Get_fixed(int i)
Definition: farm.h:638
vector< CropSort > m_variableCrops
Vector of structs containing pointers to crops which are not fixed.
Definition: farm.h:2185

References cfg_OptimiseBedriftsmodelCrops, DataForOptimisation::Get_fixed(), m_crops, m_farmType, m_fixedCrops, Farm::m_OurManager, m_variableCrops, FarmManager::pm_data, and CfgBool::value().

Referenced by createCropsLists(), and AnimalFarm::createCropsLists().

◆ crop_parameter()

double OptimisingFarm::crop_parameter ( int  index,
string  par_name 
)
protected

Reads in crop parameters that do NOT vary with any farm level parameters.

7756  {
7757  double par_value;
7759  return par_value;
7760 }
double Get_cropParameter(int i)
Definition: farm.h:622
TTypesOfParameters TranslateParametersCodes(string &str)
Definition: farm.cpp:4387
@ top_Foobar
Definition: farm.h:389

References DataForOptimisation::Get_cropParameter(), Farm::m_OurManager, FarmManager::pm_data, top_Foobar, and FarmManager::TranslateParametersCodes().

Referenced by ActualProfit(), findBIs(), findGrossMargin(), findMWeedControl(), and findYieldLoss().

◆ decreaseCrops()

void OptimisingFarm::decreaseCrops ( vector< CropSort cropsToDecrease,
double &  howMuchToDecrease 
)
protectedvirtual

Decreases area of a crops by a specified number.

Function decreases area of one or more crops from the list given as a first argument.The total area subtracted from the crops in the list is equal to the value of the second argument.

Reimplemented in AnimalFarm.

7912  {
7915  for(int j=(int)cropsToDecrease.size()-1; howMuchToDecrease>0 && j>=0; j--){ //start with the worst
7916  double areaCrop = cropsToDecrease[j].crop->m_areaPercent;
7917  double rotMinCrop = cropsToDecrease[j].crop->m_rotationMin;
7918  if(areaCrop - howMuchToDecrease >= rotMinCrop){
7919  areaCrop -= howMuchToDecrease;
7920  howMuchToDecrease = 0; //finito
7921  }
7922  else{
7923  howMuchToDecrease -= areaCrop - rotMinCrop;
7924  areaCrop = rotMinCrop;
7925  }
7926  cropsToDecrease[j].crop->m_areaPercent = areaCrop;
7927  cropsToDecrease[j].crop->m_areaVariable = areaCrop - rotMinCrop;
7928  }
7929 }

Referenced by NonAnimalFarm::checkWinterCrops(), NonAnimalFarm::checkWinterRotation1(), and AnimalFarm::determineMinFodder().

◆ determineAreas()

void OptimisingFarm::determineAreas ( int  a_foobar)
protectedvirtual

Determines areas of variable crops.

Function determining areas of all not fixed, non-fodder crops at a farm as percentages of a farm's total area. It goes through a list of variable crops sorted from the highest to the lowest Gross Margin (i.e., most to least profitable) and assigns a maximal allowed area for each non-fodder crop - until the remaining farm's area is equal to or lower than a maximal allowed area for a given crop. In such case it assigns the remaining area to this crop. All remaining crops are assigned areas equal to zero (above their minimal required areas).

If the cfg_Areas_Based_on_Distribution variable is set to true, the area is assigned on the basis og each crop's GM proportion in the summary GM based on crops with a positive GM.

Reimplemented in AnimalFarm.

6304  {
6313  m_grownVariableCrops.clear();
6314 
6315  for(int i=0; i<(int)m_variableCrops.size(); i++){
6316  double areaPercent=0;
6317  double minArea=m_variableCrops[i].crop->m_rotationMin;
6318 
6319  int index1 = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar*m_farmType + m_variableCrops[i].crop->m_cropType : a_foobar*m_farmType + m_variableCrops[i].crop->m_cropType_almass;
6320 
6321  //next two lines necessary for animal farms' function version
6322  bool fodder = m_OurManager->pm_data->Get_fodder(index1);
6323  if (!fodder){ //this should be checked for animal farms, for other and plant - will always be false
6324  if (m_assigned<100){ //check if there is any area left at a farm
6325  double rotationMax = m_variableCrops[i].crop->m_rotationMax; //same as in else
6326 
6327  if(cfg_Areas_Based_on_Distribution.value()){ //added 170713
6328 
6329  double GMsum = 0;
6330  for(int k=i; k<(int)m_variableCrops.size(); k++){ //do it for each crop (calculate prob) to avoid getting area without any crop. Start with the current crop (k=i), i.e. exclude the crops that are already assigned area.
6331  if(m_variableCrops[k].crop->m_GM > 0 && m_variableCrops[k].crop->m_rotationMax>0){ //make sure you dont include crops that have rot max set to zero! then the area won't sum up to 100%
6332  GMsum += pow (m_variableCrops[k].crop->m_GM, 1);
6333  }
6334  }
6335  double base_prob = 0;
6336  if(m_variableCrops[i].crop->m_GM > 0){
6337  base_prob = pow(m_variableCrops[i].crop->m_GM, 1)/GMsum;
6338  }
6339  else base_prob = 0;
6340 
6341  //draw a random number
6342  std::random_device rd;
6343  distribution_type3 dis(-1.0, 1.0);
6344  std::mt19937 engine(rd());
6345  double random_number = dis(engine);
6346  if(base_prob == 1) random_number = 0; // this is the last crop on the list - don't manipulate the area
6347  double area_1 = base_prob * (1 + 0.2 * random_number) * (100 - m_assigned); //take only a percent of the remaining area!
6348  areaPercent = ( area_1 <= rotationMax)? area_1 : rotationMax;
6349  if (areaPercent > 100 - m_assigned) areaPercent = 100 - m_assigned; //added 280813
6350 
6351  }
6352  else{ //standard area assignment
6353  areaPercent = (rotationMax-minArea <= 100-m_assigned)? rotationMax : (100 - m_assigned+minArea); //check if the remaining area (100-assigned) is enough to assign max allowed area for a crop (max-min, which was already assigned, if not - assign the remaining area+min area
6354  }
6355 
6356  m_assigned += areaPercent - minArea; //add the assigned area (final area percent minus minimum; minimum was assigned before) to the total assigned area
6357  if(areaPercent>minArea){m_grownVariableCrops.push_back(m_variableCrops[i].crop);} //this might not be used for other than animal farms...but maybe - it would be nice to have such a list anyway
6358 
6359  }//m_assigned < 100
6360 
6361  else {areaPercent = minArea;}
6362 
6363  m_variableCrops[i].crop->m_areaPercent = areaPercent;
6364  double areaVar=areaPercent-minArea;
6365  m_variableCrops[i].crop->m_areaVariable = areaVar; //save the value of the area that can be changed! For farms other than animal this maybe could be used just in restrictions functions...
6366  }
6367  else{ //it is a fodder crop, so just save its min area under areaPercent
6368  m_variableCrops[i].crop->m_areaPercent = minArea;
6369  }
6370  }
6371 }
boost::random::uniform_real_distribution< double > distribution_type3
Definition: BoostRandomGenerators.h:33
vector< CropOptimised * > m_grownVariableCrops
Vector of pointers to variable crops that are grown on area larger than areaMin (after determineAreas...
Definition: farm.h:2192

References cfg_Areas_Based_on_Distribution, cfg_OptimiseBedriftsmodelCrops, DataForOptimisation::Get_fodder(), m_assigned, m_farmType, m_grownVariableCrops, Farm::m_OurManager, m_variableCrops, FarmManager::pm_data, and CfgBool::value().

Referenced by AnimalFarm::determineAreas(), and OptimiseFarm().

◆ determineAreas_ha()

void OptimisingFarm::determineAreas_ha ( vector< CropOptimised * >  crops)
protected

Determines areas of crops in ha.

Determines areas of crops in ha: CropOptimised::m_area_ha = CropOptimised::m_areaPercent/100 * m_totalArea.

7967  { //area in ha
7970  for(int i=0; i<(int)allCrops.size(); i++){
7971  double areaPercent = allCrops[i]->m_areaPercent;
7972  double area_ha = (areaPercent==0) ? 0 : (areaPercent/100 * m_totalArea);
7973  allCrops[i]->m_area_ha = area_ha;
7974  }
7975 }

References m_totalArea.

Referenced by OptimiseFarm().

◆ FarmLevelCalculation()

void OptimisingFarm::FarmLevelCalculation ( )
protected

Calls functions determining farm level values before the initial optimisation.

Calls functions determining farm level values before the initial optimisation (i.e.: amount of animal fertilizer (total - m_totalNanim, and per ha - m_Nanim), farm's area - m_totalArea, and fodder demand - m_totalFUdemand).

5613  {
5614 
5615  findTotalArea();
5616  findTotalNanim();
5617  findNanim();
5618  findFodderDemand(); //this function cannot be called in the constructor!
5620  preventCashCrops();
5621  }
5622 }
void findTotalNanim()
Determines total animal fertilizer (m_totalNanim) available at a farm.
Definition: farm.cpp:5643
virtual void findFodderDemand()
Determines farm's total demand for fodder (m_totalFUdemand).
Definition: farm.cpp:5670
void findTotalArea()
Determines m_totalArea of a farm.
Definition: farm.cpp:5624
virtual void preventCashCrops()
Prevents small cattle farms from growing cash crops and maize silage.
Definition: farm.h:2293
void findNanim()
Determines amount of animal fertilizer per ha (m_Nanim) at a farm.
Definition: farm.cpp:5665

References cfg_Areas_Based_on_Distribution, findFodderDemand(), findNanim(), findTotalArea(), findTotalNanim(), preventCashCrops(), and CfgBool::value().

Referenced by Init().

◆ Find_neighbour_to_imitate()

OptimisingFarm * OptimisingFarm::Find_neighbour_to_imitate ( )

Picks randomly a farmer to imitate/compare with. It chooses among neighbouring farmers with similar farms.

Chooses a farmer for imitation and social comparison decision making modes. For business (>10 ha) farms it chooses a farmer with the same farm type and soil type. For private (<10 ha) farms it chooses a farmer with the same soil type.

5380  {
5381 
5385  int no_farmers = (int)m_neighbours.size();
5386 
5387  if(no_farmers!=0){ //if the list is empty - no neighbours
5388  bool ok=false;
5389  vector<OptimisingFarm*>neighbours_copy = m_neighbours;
5390  for(int a=0; ok==false && neighbours_copy.size()>0; a++){
5391  srand ((unsigned)time(NULL)); //warning?
5392  int neighbour = rand() % (no_farmers-a); //returns a random int number from the range: <0, no_farmers-1-a> - need to subtract those remved from the list-there is 'a' removed neighbours
5393  m_previously_imitated_neighbour = neighbours_copy[neighbour];
5394  if(m_farmSize==tofs_Private){ //then look just at the soil type
5395  if(m_soilType!=tos_Clay){ //private with sand or other soil
5398  ok=true; //found somebody to imitate
5399  }
5400  else{
5401  neighbours_copy.erase(neighbours_copy.begin() + neighbour);
5402  }
5403  }
5404  else{ //private with clay
5407  ok=true; //found somebody to imitate
5408  }
5409  else{
5410  neighbours_copy.erase(neighbours_copy.begin() + neighbour);
5411  }
5412  }
5413  }
5414  else if(m_soilType!=tos_Clay){ //business farm with sand or other soil
5417  ok=true; //found somebody to imitate
5418  }
5419  else{
5420  neighbours_copy.erase(neighbours_copy.begin() + neighbour);
5421  }
5422  }
5423  else{ //business farm with clay soil
5426  ok=true; //found somebody to imitate
5427  }
5428  else{
5429  neighbours_copy.erase(neighbours_copy.begin() + neighbour);
5430  }
5431  }
5432 
5433  }
5434  if(ok==true){ //found a neighbouring farmer to imitate
5436  }
5437  else{ //try to find a neighbour with at least the same farm type
5438  neighbours_copy = m_neighbours; //first restart the neighbours copy!
5439  for(int a=0; ok==false && neighbours_copy.size()>0; a++){ //040713 - do not accept a farm with empty rot crops
5440  srand ((unsigned)time(NULL)); //warning?
5441  int neighbour = rand() % (no_farmers-a); //returns a random int number from the range: <0, no_farmers-1-a> - need to subtract those remved from the list-there is 'a' removed neighbours
5442  m_previously_imitated_neighbour = neighbours_copy[neighbour];
5444  ok=true;
5445  }
5446  else{
5447  neighbours_copy.erase(neighbours_copy.begin() + neighbour);
5448  }
5449  }
5450  if(ok==true){
5452  }
5453  else{
5454  m_previously_imitated_neighbour = this; //no neighbour that fits - copy yourself
5455  #ifdef _DEBUG
5456  char errornum[ 20 ];
5457  sprintf( errornum, "%d", m_almass_no );
5458  g_msg->Warn( WARN_BUG, "No farm with a matching farm type to imitate: ", errornum );
5459  #endif
5461  }
5462  }
5463  }
5464 
5465 
5466  else{ //no neighboring farmers //just set yourself
5469  }
5470 }
vector< AlmassCrop > m_rotational_crops_visible
Stores a copy of m_rotational_crops from a previous year and is accessible to farmers who want to cop...
Definition: farm.h:2206
TTypesOfSoils Get_soilType(void)
Definition: farm.h:2035
TTypesOfFarmSize m_farmSize
Scale of the farm - business (size above 10 ha) or private (size below 10 ha).
Definition: farm.h:2214
TTypesOfFarmSize Get_farmSize(void)
Definition: farm.h:2036
vector< OptimisingFarm * > m_neighbours
Vector of pointers to the farms considered neighbours (fulfilling the neighbourship condition) of a g...
Definition: farm.h:2108
@ tofs_Private
Definition: farm.h:295
@ tos_Clay
Definition: farm.h:289

References g_msg, Get_farmSize(), Get_soilType(), m_almass_no, m_farmSize, m_farmType, m_neighbours, m_previously_imitated_neighbour, m_rotational_crops_visible, m_soilType, tofs_Private, tos_Clay, MapErrorMsg::Warn(), and WARN_BUG.

Referenced by ChooseDecisionMode().

◆ findBIs()

void OptimisingFarm::findBIs ( CropOptimised a_crop,
double  benefit 
)
protected

Determines the optimal Treatment frequency indices (behandling index, BI in Danish) (CropOptimised::m_BIHerb, CropOptimised::m_BIFi, CropOptimised::m_BI) for a given crop at a farm.

Function determining the optimal 'behandling indeks' (treatment frequency index) for herbicides (CropOptimised::m_BIHerb), fungicides and insecticides (CropOptimised::m_BIFi), and a summary BI per ha (CropOptimised::m_BIHerb). For each crop there is a specified amount of herbicides, fungicides and insecticides for which the yield loss is equal to zero. The farmer can choose between this value and not using pesticide at all (since yield and profit are linear functions of pesticide usage). However, when a given crop is actually grown, farmer might not apply pesticide if there is no pest problem (even though he originally planned to apply pesticides), or might apply more than he planned to if there is an excess pest problem. Therefore, there is a variation in the actual pesticide usage between farmers.

6047  {
6053  int index = (cfg_OptimiseBedriftsmodelCrops.value())? (int)a_crop->m_cropType : (int)a_crop->m_cropType_almass;
6054 
6055  double alfaFi = crop_parameter(index, "AlfaFi");
6056  double alfaHerb = crop_parameter(index, "AlfaHerb");
6057  double alfaG = crop_parameter(index, "AlfaG");
6058  double alfaH = crop_parameter(index, "AlfaH");
6059  double alfaW = crop_parameter(index, "AlfaW");
6060  double betaFi = crop_parameter(index, "BetaFi");
6061  double betaHerb = crop_parameter(index, "BetaHerb");
6062 
6063  double priceFi = crop_parameter(index, "PriceFi");
6064  double priceHerb = crop_parameter(index, "PriceHerb");
6065  double priceG = crop_parameter(index, "PriceG");
6066  double priceH = crop_parameter(index, "PriceH");
6067  double priceW = crop_parameter(index, "PriceW");
6068 
6069  double resp1=a_crop->m_resp;
6070 
6071  if(alfaHerb>0){//make sure it is not zero!it is for Fodder beet
6072  double BIHerbMax = betaHerb/alfaHerb;
6073  double gainHerb = 0;
6074  double BIHerb = 0;
6075 
6076  if(m_main_goal == tofg_profit){
6077  gainHerb = benefit*resp1*alfaHerb/100 + priceG*alfaG + priceH*alfaH + priceW*alfaW;
6078  BIHerb = (gainHerb>priceHerb)? BIHerbMax : 0;
6079  a_crop->m_BIHerb = BIHerb;
6080  }
6081  else if (m_main_goal == tofg_yield){
6082  a_crop->m_BIHerb = BIHerbMax; //12.12.12
6083  }
6084  else if (m_main_goal == tofg_environment){
6085  gainHerb = benefit*resp1*alfaHerb/100 + priceG*alfaG + priceH*alfaH + priceW*alfaW;
6086  BIHerb = (gainHerb> (priceHerb * cfg_Env_pest_multiplier.value()))? BIHerbMax : 0;
6087  a_crop->m_BIHerb = BIHerb;
6088  }
6089  }
6090  else a_crop->m_BIHerb = 0; //BI for fodder beet in the original model (Bedriftsmodel)
6091 
6092  if(alfaFi>0){
6093  double BIFiMax = betaFi/alfaFi;
6094  double gainFi = 0;
6095  double BIFi = 0;
6096  if(m_main_goal == tofg_profit){
6097  gainFi = benefit*resp1*alfaFi/100;
6098  BIFi = (gainFi > priceFi) ? BIFiMax : 0;
6099  a_crop->m_BIFi = BIFi;
6100  }
6101  else if (m_main_goal == tofg_yield){
6102  a_crop->m_BIFi = BIFiMax;
6103  }
6104  else if (m_main_goal == tofg_environment){
6105  gainFi = benefit*resp1*alfaFi/100;
6106  if (gainFi > (priceFi * cfg_Env_pest_multiplier.value())){
6107  BIFi = BIFiMax;
6108  }
6109  else{
6110  BIFi = 0;
6111  }
6112  a_crop->m_BIFi = BIFi;
6113  }
6114  }
6115  else a_crop->m_BIFi = 0;
6116 
6117  double BIFi = a_crop->m_BIFi;
6118  double BIHerb = a_crop->m_BIHerb;
6119  double BI = BIFi+BIHerb;
6120  a_crop->m_BI = BI;
6121 }
double m_BIFi
Value of BI for fung- and insecticides [BI/ha].
Definition: farm.h:1669
double m_BIHerb
Value of BI for herbicides [BI/ha].
Definition: farm.h:1667
TTypesOfCrops m_cropType
Type/name of a crop (original farm optimization model crop types).
Definition: farm.h:1644
double m_BI
Summary value of BI for herbicides and fung- and insecticides [BI/ha].
Definition: farm.h:1671
CfgFloat cfg_Env_pest_multiplier("ENV_PEST_MULTIPLIER", CFG_CUSTOM, 1.25)
A parameter of the environmentalist farmer type: increases the chance that environmentalist does not ...

References cfg_Env_pest_multiplier, cfg_OptimiseBedriftsmodelCrops, crop_parameter(), CropOptimised::m_BI, CropOptimised::m_BIFi, CropOptimised::m_BIHerb, CropOptimised::m_cropType, CropOptimised::m_cropType_almass, m_main_goal, CropOptimised::m_resp, tofg_environment, tofg_profit, tofg_yield, CfgFloat::value(), and CfgBool::value().

Referenced by optimizeCrops().

◆ findCropByName()

CropOptimised * OptimisingFarm::findCropByName ( string  crop_name)
protected

Returns a pointer to a crop whose name is specified as the argument (bedriftsmodel, i.e. original farm optimization model, crops mode).

7762  {
7763  for(int c=0; c< (int)m_crops.size(); c++){
7764  if(m_crops[c]->m_cropType==m_OurManager->TranslateCropsCodes(crop_name)) return m_crops[c];
7765  }
7766  g_msg->Warn( WARN_FILE, "OptimisingFarm::findCropByName():" "Unknown Code Identificator", crop_name.c_str() );
7767  exit(0);
7768 }
TTypesOfCrops TranslateCropsCodes(string &str)
Definition: farm.cpp:4338
@ WARN_FILE
Definition: maperrormsg.h:37

References g_msg, m_crops, Farm::m_OurManager, FarmManager::TranslateCropsCodes(), MapErrorMsg::Warn(), and WARN_FILE.

Referenced by OptimisingCattleFarm::checkCattleRotation(), AnimalFarm::checkWinterCrops(), NonAnimalFarm::checkWinterCrops(), AnimalFarm::checkWinterRotation1(), NonAnimalFarm::checkWinterRotation1(), fixBI(), and Make_rotations().

◆ findCropByName_almass() [1/2]

CropOptimised * OptimisingFarm::findCropByName_almass ( string  crop_name)
protected

Returns a pointer to almass crop whose name is specified as the argument (ALMaSS crops mode).

7770  {
7771  for(int c=0; c< (int)m_crops.size(); c++){
7772  if(m_crops[c]->m_cropType_almass == m_OurManager->TranslateCropCodes(crop_name)) return m_crops[c];
7773  }
7774  g_msg->Warn( WARN_FILE, "OptimisingFarm::findCropByName_almass():" "Unknown Code Identificator", crop_name.c_str() );
7775  exit(0);
7776 }
TTypesOfVegetation TranslateCropCodes(std::string &str)
Definition: farm.cpp:1818

References g_msg, m_crops, Farm::m_OurManager, FarmManager::TranslateCropCodes(), MapErrorMsg::Warn(), and WARN_FILE.

Referenced by ActualProfit(), Check_SG_and_CGG(), OptimisingPigFarm::check_WRape_WBarley(), OptimisingCattleFarm::checkCattleRotation_almass(), AnimalFarm::checkWinterCrops(), NonAnimalFarm::checkWinterCrops(), AnimalFarm::checkWinterRotation1(), NonAnimalFarm::checkWinterRotation1(), fixBI(), Make_rotations(), OptimisingCattleFarm::preventCashCrops(), Spraying_fungins(), and Spraying_herbicides().

◆ findCropByName_almass() [2/2]

CropOptimised * OptimisingFarm::findCropByName_almass ( TTypesOfVegetation  a_tov_type)
protected

Returns a pointer to almass crop whose tov type is specified as the argument.

7778  {
7779  for(int c=0; c< (int)m_crops.size(); c++){
7780  if(m_crops[c]->m_cropType_almass == a_tov_type) return m_crops[c];
7781  }
7782  char error_num[ 20 ];
7783  sprintf( error_num, "%d", a_tov_type);
7784  g_msg->Warn( WARN_BUG, "OptimisingFarm::findCropByName_almass():" "Unknown Code Identificator", error_num );
7785  exit(0);
7786 }

References g_msg, m_crops, MapErrorMsg::Warn(), and WARN_BUG.

◆ findFertilizer()

void OptimisingFarm::findFertilizer ( CropOptimised a_crop,
int  a_foobar,
double  benefit 
)
protected

Determines the optimal amounts of: total fertilizer (CropOptimised::m_n) and purchased fertilizer (CropOptimised::m_nt) for a given crop at a farm.

Function determining the optimal amounts of: total fertilizer (CropOptimised::m_n) and purchased fertilizer (CropOptimised::m_nt) per ha of a crop at a given farm. [kg/ha]

5906  {
5907 
5911  int index = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar * m_soilType + a_crop->m_cropType : a_foobar * m_soilType + a_crop->m_cropType_almass;
5912 
5913  double beta1=m_OurManager->pm_data->Get_beta1(index);
5914  double beta2=m_OurManager->pm_data->Get_beta2(index);
5915  double nNorm=m_OurManager->pm_data->Get_Nnorm(index);
5916  double priceNt=cfg_Price_Nt.value();
5917 
5918  if(!beta2==0){
5919  a_crop->m_optimalN = -(beta1/beta2)*0.5; //01.03.12 save the optimal free fertilizer
5920  }
5921  else{ //if beta2 is =0, beta1 is also =0 -> so optimum is at 0.
5922  a_crop->m_optimalN = 0;
5923  }
5924 
5925  if(m_main_goal == tofg_profit){
5926 
5927  if(!beta2==0){ //beta2 is not 0
5928  double n1=-(beta1/beta2)*0.5; //optimal fertilizer supposing it's for free
5929  if(m_Nanim >= n1){ //there is more than you need, so check the norm:
5930  if (n1<nNorm){
5931  a_crop->m_n = n1; //apply optimal amount
5932  }
5933  else {
5934  a_crop->m_n = nNorm; //apply max allowed amount
5935  }
5936  a_crop->m_nt = 0; //don't buy fertilizer
5937  }
5938  else { //the optimal amount is larger than Nanim
5939  double nt1= 0.5*(priceNt/(benefit*beta2) - beta1/beta2) - m_Nanim; //optimal fertilizer Nt
5940  if (nt1>0){
5941  double n2=nt1+m_Nanim; //optimal total N
5942  if (n2<nNorm){
5943  a_crop->m_nt = nt1;
5944  a_crop->m_n = n2;
5945  }
5946  else {
5947  double p=nNorm-m_Nanim;
5948  if(p>=0){a_crop->m_nt = p;} //buy the diff between what you have (Nanim) and what is the max allowed
5949  else{a_crop->m_nt = 0;}// your Nanim is higher than the norm!
5950  a_crop->m_n = nNorm; //total amount is the max allowed, Nanim+(nNorm-Nanim)=nNorm
5951  }
5952  }
5953  else { //it doesn't pay off to buy fertilizer, so just use Nanim
5954  if(m_Nanim<=nNorm){a_crop->m_n = m_Nanim;} //apply fertilizer
5955  else {a_crop->m_n = nNorm;}
5956  a_crop->m_nt = 0;
5957  }
5958  }
5959  }
5960  else{ //beta2=0, so don't apply fertilizer, but in this model - apply Nanim if there is any
5961  if(m_Nanim<=nNorm){a_crop->m_n = m_Nanim;} //apply fertilizer
5962  else {a_crop->m_n = nNorm;}
5963  a_crop->m_nt = 0;
5964  }
5965 
5966  }
5967 
5968  else if (m_main_goal == tofg_yield) { //modified profit optimization algorithm
5969  if(!beta2==0){ //beta2 is not 0
5970  double n1=-(beta1/beta2)*0.5; //optimal fertilizer supposing it's for free
5971  if(m_Nanim >= n1){ //there is more than you need, so check the norm:
5972  if (n1<nNorm){
5973  a_crop->m_n = n1; //apply optimal amount
5974  }
5975  else {
5976  a_crop->m_n = nNorm; //apply max allowed amount
5977  }
5978  a_crop->m_nt = 0; //don't buy fertilizer
5979  }
5980  else { //the optimal amount is larger than Nanim
5981  if(n1>=nNorm){
5982  if(m_Nanim > nNorm){a_crop->m_nt = 0;}
5983  else{a_crop->m_nt = nNorm - m_Nanim;}//buy the diff between what you have (Nanim) and what is the max allowed
5984  a_crop->m_n = nNorm; //total amount is the max allowed
5985  }
5986  else{
5987  a_crop->m_nt = n1 - m_Nanim;
5988  a_crop->m_n = n1;
5989  }
5990  }
5991  }
5992  else{ //beta2=0, so don't apply fertilizer, but in this model - apply Nanim if there is any
5993  if(m_Nanim<=nNorm){a_crop->m_n = m_Nanim;} //apply fertilizer
5994  else {a_crop->m_n = nNorm;}
5995  a_crop->m_nt = 0;
5996  }
5997 
5998  }
5999  else if (m_main_goal == tofg_environment) { //apply less than a norm: the code copied from yield max - the only change is in calculation of n1 - mulitplied by 0.8.
6000  if(!beta2==0){ //beta2 is not 0
6001  double n1=-(beta1/beta2)*0.5 * cfg_Env_fert_multiplier.value(); //optimal fertilizer supposing it's for free; multiplier - to make this type use less fertilizer
6002  if(m_Nanim >= n1){ //there is more than you need, so check the norm:
6003  if (n1<nNorm){
6004  a_crop->m_n = n1; //apply optimal amount
6005  }
6006  else {
6007  a_crop->m_n = nNorm; //apply max allowed amount
6008  }
6009  a_crop->m_nt = 0; //don't buy fertilizer
6010  }
6011  else { //the optimal amount is larger than Nanim
6012  if(n1>=nNorm){
6013  if(m_Nanim > nNorm){a_crop->m_nt = 0;}
6014  else{a_crop->m_nt = nNorm - m_Nanim;}//buy the diff between what you have (Nanim) and what is the max allowed
6015  a_crop->m_n = nNorm; //total amount is the max allowed
6016  }
6017  else{
6018  a_crop->m_nt = n1 - m_Nanim;
6019  a_crop->m_n = n1;
6020  }
6021  }
6022  }
6023  else{ //beta2=0, so don't apply fertilizer, but in this model - apply Nanim if there is any
6024  if(m_Nanim<=nNorm){a_crop->m_n = m_Nanim;} //apply fertilizer
6025  else {a_crop->m_n = nNorm;}
6026  a_crop->m_nt = 0;
6027  }
6028  }
6029 }
double Get_Nnorm(int i)
Definition: farm.h:631
double m_Nanim
Amount of animal fertilizer available at a farm per hectar. [kg/ha].
Definition: farm.h:2232
CfgFloat cfg_Env_fert_multiplier("ENV_FERT_MULTIPLIER", CFG_CUSTOM, 0.8)
A parameter of the environmentalist farmer type: reduces environmentalist's use of fertiliser....

References cfg_Env_fert_multiplier, cfg_OptimiseBedriftsmodelCrops, cfg_Price_Nt, DataForOptimisation::Get_beta1(), DataForOptimisation::Get_beta2(), DataForOptimisation::Get_Nnorm(), CropOptimised::m_cropType, CropOptimised::m_cropType_almass, m_main_goal, CropOptimised::m_n, m_Nanim, CropOptimised::m_nt, CropOptimised::m_optimalN, Farm::m_OurManager, m_soilType, FarmManager::pm_data, tofg_environment, tofg_profit, tofg_yield, CfgFloat::value(), and CfgBool::value().

Referenced by optimizeCrops().

◆ findFodderDemand()

void OptimisingFarm::findFodderDemand ( )
protectedvirtual

Determines farm's total demand for fodder (m_totalFUdemand).

Function determining farm's demand for fodder. Sums fodder needed for all types of livestock.

Reimplemented in NonAnimalFarm.

5670  {
5673  m_totalFUdemand=0;
5674  for(int i=0; i< (int) m_livestock.size(); i++){
5675  string str_FUuKey="FUuKey";
5676  TTypesOfAnimals index=m_livestock[i]->m_animalType;
5677  double FUuKey=m_OurManager->pm_data->Get_livestockParameter(tolp_Foobar*index + m_OurManager->TranslateLivestockParametersCodes(str_FUuKey)); //number of fodder units needed per one animal per year
5678  double number = m_livestock[i]->m_number;
5679 
5680  if(!cfg_UseBedriftsmodelFarmAreas.value()){ //almass farm areas - need to scale the livestock numbers; we don't even have to take integer...
5681  number *= m_area_scaling_factor;
5682  }
5683 
5684  if(number>0){
5685  double FUdemand=FUuKey*number;
5686  m_livestock[i]->m_FUdemand = FUdemand;
5687  m_totalFUdemand+=FUdemand;
5688  }
5689  }
5690  m_totalFUdemandBefore=m_totalFUdemand; //just to know afterwards the total demand
5691 }
double Get_livestockParameter(int i)
Definition: farm.h:618
TTypesOfLivestockParameters TranslateLivestockParametersCodes(string &str)
Definition: farm.cpp:4414
vector< Livestock * > m_livestock
Vector of pointers to animals belonging to a farm.
Definition: farm.h:2181
@ tolp_Foobar
Definition: farm.h:396
TTypesOfAnimals
Definition: farm.h:299

References cfg_UseBedriftsmodelFarmAreas, DataForOptimisation::Get_livestockParameter(), m_area_scaling_factor, m_livestock, Farm::m_OurManager, m_totalFUdemand, m_totalFUdemandBefore, FarmManager::pm_data, tolp_Foobar, FarmManager::TranslateLivestockParametersCodes(), and CfgBool::value().

Referenced by FarmLevelCalculation(), and NonAnimalFarm::findFodderDemand().

◆ findGrossMargin()

void OptimisingFarm::findGrossMargin ( CropOptimised a_crop,
int  a_foobar,
double  benefit 
)
protected

Determines the gross margin (CropOptimised::m_GM) for a given crop at a farm.

Function determining gross margin (CropOptimised::m_GM, i.e. profit per ha for a given crop; it might be positive only for non-fodder crops) and savings (CropOptimised::m_savings, savings from growing a fodder crop per ha, it equals zero for all non-fodder crops). [DKK]

6225  {
6229  int index = (cfg_OptimiseBedriftsmodelCrops.value())? (int) a_crop->m_cropType : (int) a_crop->m_cropType_almass;
6230 
6231  double priceFi = crop_parameter(index, "PriceFi");
6232  double priceHerb =crop_parameter(index, "PriceHerb");
6233  double priceG =crop_parameter(index, "PriceG");
6234  double priceH =crop_parameter(index, "PriceH");
6235  double priceW =crop_parameter(index, "PriceW");
6236  double priceLM =crop_parameter(index, "PriceLM");
6237  double subsidy =crop_parameter(index, "Subsidy");
6238 
6239  double resp = a_crop->m_resp;
6240  double BIHerb = a_crop->m_BIHerb;
6241  double BIFi = a_crop->m_BIFi;
6242  double grooming = a_crop->m_grooming;
6243  double hoeing = a_crop->m_hoeing;
6244  double weeding = a_crop->m_weeding;
6245  double totalLoss = a_crop->m_totalLoss;
6246  double nt = a_crop->m_nt;
6247  double priceNt = cfg_Price_Nt.value();
6248 
6249  double income_ha = benefit*resp*(1-totalLoss/100)+subsidy;
6250  double costs_ha = BIHerb*priceHerb + BIFi*priceFi + grooming*priceG + hoeing*priceH + weeding*priceW + nt*priceNt + priceLM;
6251  double profit = income_ha - costs_ha;
6252 
6253  a_crop->m_costs_ha = costs_ha;
6254  a_crop->m_GM_Savings = profit;
6255 
6256  //29.02.12
6257  int index1 = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar * m_farmType + a_crop->m_cropType : a_foobar * m_farmType + a_crop->m_cropType_almass;
6258  bool fodder = m_OurManager->pm_data->Get_fodder(index1);
6259  if (fodder){
6260  a_crop->m_income_ha = subsidy; //because fodder crops can't be sold
6261  a_crop->m_GM = subsidy-costs_ha; //because fodder crops can't be sold
6262  a_crop->m_savings = profit;
6263  }
6264  else{
6265  a_crop->m_income_ha = income_ha;
6266  a_crop->m_GM = profit;
6267  a_crop->m_savings = 0; //this is not a fodder crop!
6268  }
6269 }
double m_GM
Value of gross margin for a crop (m_income_ha - m_costs_ha) [DKK/ha].
Definition: farm.h:1689
double m_savings
Value of savings resulting from growing a fodder crop and not purchasing amount of fodder correspondi...
Definition: farm.h:1691
double m_GM_Savings
Holds the value of m_GM in case of non-fodder crops and a value of m_savings in case of fodder crops ...
Definition: farm.h:1693
double m_income_ha
Value of income per ha of a crop. Includes value of sales and subsidy [DKK/ha].
Definition: farm.h:1687

References cfg_OptimiseBedriftsmodelCrops, cfg_Price_Nt, crop_parameter(), DataForOptimisation::Get_fodder(), CropOptimised::m_BIFi, CropOptimised::m_BIHerb, CropOptimised::m_costs_ha, CropOptimised::m_cropType, CropOptimised::m_cropType_almass, m_farmType, CropOptimised::m_GM, CropOptimised::m_GM_Savings, CropOptimised::m_grooming, CropOptimised::m_hoeing, CropOptimised::m_income_ha, CropOptimised::m_nt, Farm::m_OurManager, CropOptimised::m_resp, CropOptimised::m_savings, CropOptimised::m_totalLoss, CropOptimised::m_weeding, FarmManager::pm_data, CfgFloat::value(), and CfgBool::value().

Referenced by optimizeCrops().

◆ findMWeedControl()

void OptimisingFarm::findMWeedControl ( CropOptimised a_crop)
protected

Determines the optimal mechanical weed control means (CropOptimised::m_grooming, CropOptimised::m_hoeing, CropOptimised::m_weeding) for a given crop at a farm.

Function determining optimal values of mechanical weed control means: grooming (CropOptimised::m_grooming), hoeing (CropOptimised::m_hoeing) and weeding (CropOptimised::m_weeding). All of them are functions of treatment frequency index (behandling indeks) for herbicides (CropOptimised::m_BIHerb).

6153  {
6157  int index = (cfg_OptimiseBedriftsmodelCrops.value())? (int) a_crop->m_cropType : (int) a_crop->m_cropType_almass;
6158 
6159  double betaG = crop_parameter(index, "BetaG");
6160  double betaH = crop_parameter(index, "BetaH");
6161  double betaW = crop_parameter(index, "BetaW");
6162  double alfaG = crop_parameter(index, "AlfaG");
6163  double alfaH = crop_parameter(index, "AlfaH");
6164  double alfaW = crop_parameter(index, "AlfaW");
6165  double BIHerb = a_crop->m_BIHerb;
6166 
6167  double grooming, hoeing, weeding =0;
6168  double g = betaG - BIHerb*alfaG;
6169  double h = betaH - BIHerb*alfaH;
6170  double w = betaW - BIHerb*alfaW;
6171  double BIHerbCorr = BIHerb;
6172 
6173  if(g <= 0){
6174  grooming=0;
6175  if(alfaG!=0) BIHerbCorr=betaG/alfaG;
6176  }
6177  else{grooming=g;}
6178  if(h <= 0){
6179  hoeing=0;
6180  if(betaH/alfaH < BIHerbCorr) BIHerbCorr=betaH/alfaH;
6181  }
6182  else{hoeing=h;}
6183  if(w <= 0){
6184  weeding=0;
6185  if(betaW/alfaW < BIHerbCorr) BIHerbCorr = betaW/alfaW;
6186  }
6187  else{weeding=w;}
6188 
6189 
6190  a_crop->m_grooming = grooming;
6191  a_crop->m_hoeing = hoeing;
6192  a_crop->m_weeding = weeding;
6193  if(BIHerbCorr < BIHerb){
6194  a_crop->m_BIHerb = BIHerbCorr;
6195  a_crop->m_BI = a_crop->m_BIHerb + a_crop->m_BIFi;
6196  }
6197 
6198 }

References cfg_OptimiseBedriftsmodelCrops, crop_parameter(), CropOptimised::m_BI, CropOptimised::m_BIFi, CropOptimised::m_BIHerb, CropOptimised::m_cropType, CropOptimised::m_cropType_almass, CropOptimised::m_grooming, CropOptimised::m_hoeing, CropOptimised::m_weeding, and CfgBool::value().

Referenced by optimizeCrops().

◆ findNanim()

void OptimisingFarm::findNanim ( )
protected

Determines amount of animal fertilizer per ha (m_Nanim) at a farm.

Determines m_Nanim - amount of animal fertilizer per ha for a farm.

5665  {
5668  }
double m_totalNanim
Total animal fertilizer at a farm. A sum of Livestock::m_NanimUsable (from all types of livestock)....
Definition: farm.h:2230

References m_Nanim, m_totalArea, and m_totalNanim.

Referenced by FarmLevelCalculation().

◆ findResponse()

void OptimisingFarm::findResponse ( CropOptimised a_crop,
int  a_foobar 
)
protected

Determines the response (CropOptimised::m_resp) of a crop at a farm.

Function determining the response of a crop (yield per ha), CropOptimised::m_resp. It is a function of a total fertilizer (CropOptimised::m_n) applied for a crop at a given farm. [hkg/ha]

6031  {
6032 
6036  int index = (cfg_OptimiseBedriftsmodelCrops.value())? a_foobar * m_soilType + a_crop->m_cropType : a_foobar * m_soilType + a_crop->m_cropType_almass;
6037 
6038  double beta1=m_OurManager->pm_data->Get_beta1(index);
6039  double beta2=m_OurManager->pm_data->Get_beta2(index);
6040  double alfa=m_OurManager->pm_data->Get_alfa(index);
6041 
6042  double ntotal=a_crop->m_n;
6043  double resp1=alfa + beta1*ntotal + beta2*pow(ntotal,2);
6044  a_crop->m_resp = resp1;
6045 }
double Get_alfa(int i)
Definition: farm.h:625

References cfg_OptimiseBedriftsmodelCrops, DataForOptimisation::Get_alfa(), DataForOptimisation::Get_beta1(), DataForOptimisation::Get_beta2(), CropOptimised::m_cropType, CropOptimised::m_cropType_almass, CropOptimised::m_n, Farm::m_OurManager, CropOptimised::m_resp, m_soilType, FarmManager::pm_data, and CfgBool::value().

Referenced by optimizeCrops().

◆ findTotalArea()

void OptimisingFarm::findTotalArea ( )
protected

Determines m_totalArea of a farm.

Function determining farm's total area. Depending on which area is to be used it either sums initial crop areas on a farm (to get area equal to area used in Bedriftsmodel) or deteremines area based on farm's fields size.

5624  {
5629  m_totalArea=0.;
5630  for (int i=0; i< (int) m_crops.size(); i++) {
5631  m_totalArea+=m_crops[i]->m_initialArea;
5632  }
5634 
5635  if(!cfg_UseBedriftsmodelFarmAreas.value()){ //almass farm areas used: just sum the fields area
5636  double area_copy = m_totalArea; //ha
5637  m_totalArea = GetAreaDouble()/10000; //change from sq m to ha
5638  m_area_scaling_factor = m_totalArea/area_copy;
5639  }
5640  //otherwise do nothing: total area = sum of initial crop areas (see the for loop)
5641 }
double GetAreaDouble(void)
Returns the area of arable fields owned by that farm.
Definition: farm.cpp:1350
double m_totalArea_original
Total area of a farm as in bedriftsmodel, i.e. original farm optimization model. [ha].
Definition: farm.h:2226

References cfg_UseBedriftsmodelFarmAreas, Farm::GetAreaDouble(), m_area_scaling_factor, m_crops, m_totalArea, m_totalArea_original, and CfgBool::value().

Referenced by FarmLevelCalculation().

◆ findTotalNanim()

void OptimisingFarm::findTotalNanim ( )
protected

Determines total animal fertilizer (m_totalNanim) available at a farm.

Function determining farm's total animal fertilizer. Sums usable fertilizer from all types of livestock.

5643  {
5646  m_totalNanim = 0;
5647  for (int i=0; i< (int) m_livestock.size(); i++){
5648  string str_AUKey="AUKey";
5649  string str_Nusable="Nusable";
5650  TTypesOfAnimals index=m_livestock[i]->m_animalType;
5651  double AUKey = m_OurManager->pm_data->Get_livestockParameter(tolp_Foobar*index + m_OurManager->TranslateLivestockParametersCodes(str_AUKey)); //Number of animal units (AU, DE-dyreenheder) -> hkg N per year
5652  double Nusable = m_OurManager->pm_data->Get_livestockParameter(tolp_Foobar*index + m_OurManager->TranslateLivestockParametersCodes(str_Nusable)); // [%] Usable fertilizer from livestock
5653  double number = m_livestock[i]->m_number;
5654 
5655  if(!cfg_UseBedriftsmodelFarmAreas.value()){ //almass farm areas - need to scale the livestock numbers; we don't even have to take integer...
5656  number *= m_area_scaling_factor;
5657  }
5658 
5659  double NanimUsable = number*AUKey*Nusable*100; // [1*hkg/yr*1*100 = kg/yr] Usable fertilizer from livestock
5660  m_livestock[i]->m_NanimUsable = NanimUsable;
5661  m_totalNanim += NanimUsable;
5662  }
5663 }

References cfg_UseBedriftsmodelFarmAreas, DataForOptimisation::Get_livestockParameter(), m_area_scaling_factor, m_livestock, Farm::m_OurManager, m_totalNanim, FarmManager::pm_data, tolp_Foobar, FarmManager::TranslateLivestockParametersCodes(), and CfgBool::value().

Referenced by FarmLevelCalculation().

◆ findYieldLoss()

void OptimisingFarm::findYieldLoss ( CropOptimised a_crop)
protected

Determines the yield losses (CropOptimised::m_lossHerb, CropOptimised::m_lossFi, CropOptimised::m_totalLoss) for a given crop at a farm.

Function determining yield losses resulting from not using maximal amount of herbicides (CropOptimised::m_lossHerb), fungicides and insecticides (CropOptimised::m_lossFi) and a total yield loss, which is a sum of m_lossHerb and m_lossFi (CropOptimised::m_totalLoss). Losses are expressed as percentages of yield (take values from 0 to 100).

6200  {
6205  int index = (cfg_OptimiseBedriftsmodelCrops.value())? (int) a_crop->m_cropType : (int) a_crop->m_cropType_almass;
6206 
6207  double alfaFi = crop_parameter(index, "AlfaFi");
6208  double alfaHerb = crop_parameter(index, "AlfaHerb");
6209  double betaFi = crop_parameter(index, "BetaFi");
6210  double betaHerb = crop_parameter(index, "BetaHerb");
6211 
6212  double BIHerb=a_crop->m_BIHerb;
6213  double BIFi=a_crop->m_BIFi;
6214 
6215  double lossHerb = betaHerb - alfaHerb*BIHerb;
6216  a_crop->m_lossHerb = lossHerb;
6217 
6218  double lossFi = betaFi - alfaFi*BIFi;
6219  a_crop->m_lossFi = lossFi;
6220 
6221  double totalLoss = lossHerb + lossFi;// [%]
6222  a_crop->m_totalLoss = totalLoss;
6223 }
double m_lossHerb
Value of the yield loss due to the limited use of herbicides [%].
Definition: farm.h:1679
double m_lossFi
Value of the yield loss due to the limited use of fung- and insecticides [%].
Definition: farm.h:1681

References cfg_OptimiseBedriftsmodelCrops, crop_parameter(), CropOptimised::m_BIFi, CropOptimised::m_BIHerb, CropOptimised::m_cropType, CropOptimised::m_cropType_almass, CropOptimised::m_lossFi, CropOptimised::m_lossHerb, CropOptimised::m_totalLoss, and CfgBool::value().

Referenced by optimizeCrops().

◆ fixBI()

void OptimisingFarm::fixBI ( )
protected

Sets values of Treatment frequency indices (BI) for crops with fixed amount of pesticides (CropOptimised::m_BIHerb for FodderBeet and both CropOptimised::m_BIHerb and CropOptimised::m_BIFi for PotatoesIndustry and Potatoes).

6123  {
6124 
6125  if(cfg_OptimiseBedriftsmodelCrops.value()){ //b. crops
6126  CropOptimised *fodderBeet = findCropByName ("FodderBeet");
6127  CropOptimised *sugarBeet = findCropByName ("SugarBeet");
6128  CropOptimised *potato = findCropByName ("Potato");
6129  CropOptimised *potatoFood = findCropByName ("PotatoFood");
6130 
6131  fodderBeet->m_BIHerb = 2.28; //seems it's constant - in the results of Bedriftsmodel, but herbicide parameters are = zero!
6132  sugarBeet->m_BIHerb = 2.28;
6133  fodderBeet->m_BI = fodderBeet->m_BIFi + fodderBeet->m_BIHerb;
6134  sugarBeet->m_BI = sugarBeet->m_BIFi + sugarBeet->m_BIHerb;
6135 
6136  //potatoes - everything fixed
6137  potato->m_BIHerb = 1.41; potato->m_BIFi = 9.28; potato->m_BI = 10.69;
6138  potatoFood->m_BIHerb = 1.41; potatoFood->m_BIFi = 9.28; potatoFood->m_BI = 10.69;
6139  }
6140  else{ //almass crops
6141  CropOptimised *FodderBeet = findCropByName_almass ("FodderBeet");
6142  CropOptimised *PotatoesIndustry = findCropByName_almass ("PotatoesIndustry");
6143  CropOptimised *Potatoes = findCropByName_almass ("Potatoes");
6144 
6145  FodderBeet->m_BIHerb = 2.28; //the values have to be now like in the bedriftsmodel //modified probability
6146  FodderBeet->m_BI = FodderBeet->m_BIHerb + FodderBeet->m_BIFi;
6147  PotatoesIndustry->m_BIHerb = 1.41; PotatoesIndustry->m_BIFi = 9.28; PotatoesIndustry->m_BI = 10.69;
6148  Potatoes->m_BIHerb = 1.41; Potatoes->m_BIFi = 9.28; Potatoes->m_BI = 10.69;
6149  }
6150 
6151 }
CropOptimised * findCropByName(string crop_name)
Returns a pointer to a crop whose name is specified as the argument (bedriftsmodel,...
Definition: farm.cpp:7762

References cfg_OptimiseBedriftsmodelCrops, findCropByName(), findCropByName_almass(), CropOptimised::m_BI, CropOptimised::m_BIFi, CropOptimised::m_BIHerb, and CfgBool::value().

Referenced by optimizeCrops().

◆ FungicideTreat()

bool OptimisingFarm::FungicideTreat ( LE a_field,
double  ,
int  a_days 
)
protectedvirtual

Carries out fungicide application. Saves information on each application for a given crop.

Reimplemented from Farm.

1308 {
1309 
1310  if (0 >= a_days)
1311  {
1312  if ( ( ! a_field->GetSignal() & LE_SIG_NO_FUNGICIDE )) {
1313  a_field->Trace( fungicide_treat );
1314  a_field->SetLastTreatment( fungicide_treat );
1317 
1319  Field * pf = dynamic_cast<Field*>(a_field);
1320  pf->Add_no_fi_app();
1321  }
1322  }
1323  return true;
1324  }
1325  else if ( (g_weather->GetWind()<4.5) && (!g_weather->Raining()) && DoIt(DO_IT_PROB)) {
1326  if ( ! (a_field->GetSignal() & LE_SIG_NO_FUNGICIDE) ) {
1327  a_field->Trace( fungicide_treat );
1328  a_field->SetLastTreatment( fungicide_treat );
1331 
1333  Field * pf = dynamic_cast<Field*>(a_field);
1334  pf->Add_no_fi_app();
1335  }
1336  }
1337  return true;
1338  }
1339  return false;
1340 }
bool DoIt(double a_probability)
Return chance out of 0 to 100.
Definition: farm.cpp:800
Definition: elements.h:728
void SetTramlinesDecay(int a_decaytime_days)
Definition: elements.h:310
void Trace(int a_value)
Definition: elements.cpp:457
void SetLastTreatment(int a_treatment)
Definition: elements.cpp:490
LE_Signal GetSignal(void)
Definition: elements.h:107
void CheckForPesticideRecord(LE *a_field, TTypesOfPesticideCategory a_pcide)
Check if needed and record pesticide application.
Definition: Landscape.cpp:669
void Add_no_fi_app()
Definition: elements.h:650
double GetWind(long a_date)
Definition: weather.h:425
bool Raining(void)
Definition: weather.h:432
#define EL_TRAMLINE_DECAYTIME
Definition: elements.h:57
#define LE_SIG_NO_FUNGICIDE
Definition: elements.h:42
#define DO_IT_PROB
Definition: farmfuncs.cpp:56
CfgBool cfg_OptimiseBedriftsmodelCrops
Landscape * g_landscape_p
Definition: Landscape.cpp:258
@ fungicide
Definition: landscape.h:63
@ fungicide_treat
Definition: treatment.h:73
class Weather * g_weather
Definition: weather.cpp:41

References VegElement::Add_no_fi_app(), cfg_OptimiseBedriftsmodelCrops, Landscape::CheckForPesticideRecord(), DO_IT_PROB, EL_TRAMLINE_DECAYTIME, fungicide, fungicide_treat, g_landscape_p, g_weather, LE::GetSignal(), Weather::GetWind(), LE_SIG_NO_FUNGICIDE, Weather::Raining(), LE::SetLastTreatment(), LE::SetTramlinesDecay(), LE::Trace(), and CfgBool::value().

◆ Get_actual_aggregated_yield()

double OptimisingFarm::Get_actual_aggregated_yield ( )
inline
2054 {return m_actual_aggregated_yield;};

References m_actual_aggregated_yield.

Referenced by ChooseDecisionMode().

◆ Get_actual_profit()

double OptimisingFarm::Get_actual_profit ( )
inline
2053 {return m_actual_profit;};

References m_actual_profit.

Referenced by ChooseDecisionMode().

◆ Get_almass_no()

◆ Get_crop()

CropOptimised* OptimisingFarm::Get_crop ( int  i)
inline
2040 {return m_crops[i];}

References m_crops.

Referenced by FarmManager::CropDistribution(), and FarmManager::PrintOutput().

◆ Get_cropsSize()

int OptimisingFarm::Get_cropsSize ( void  )
inline
2041 {return (int)m_crops.size();}

References m_crops.

Referenced by FarmManager::CropDistribution(), and FarmManager::PrintOutput().

◆ Get_decision_mode_counters()

int OptimisingFarm::Get_decision_mode_counters ( int  index)
inline

◆ Get_farmRealID()

int OptimisingFarm::Get_farmRealID ( void  )
inline
2037 {return m_farmRealID;}
int m_farmRealID
Farm's real ID number.
Definition: farm.h:2216

References m_farmRealID.

◆ Get_farmSize()

TTypesOfFarmSize OptimisingFarm::Get_farmSize ( void  )
inline
2036 {return m_farmSize;}

References m_farmSize.

Referenced by Find_neighbour_to_imitate().

◆ Get_farmType()

TTypesOfOptFarms OptimisingFarm::Get_farmType ( void  )
inline
2034 {return m_farmType;}

References m_farmType.

Referenced by FarmManager::Save_diff_farm_types_areas().

◆ Get_main_goal()

TTypeOfFarmerGoal OptimisingFarm::Get_main_goal ( )
inline
2058 {return m_main_goal;};

References m_main_goal.

Referenced by FarmManager::FarmManagement().

◆ Get_Neighbour()

OptimisingFarm* OptimisingFarm::Get_Neighbour ( int  i)
inline
2050 {return m_neighbours[i];};

References m_neighbours.

Referenced by FarmManager::PrintNeighbours().

◆ Get_NeighboursSize()

int OptimisingFarm::Get_NeighboursSize ( void  )
inline
2049 {return (int)m_neighbours.size();};

References m_neighbours.

Referenced by FarmManager::PrintNeighbours().

◆ Get_rotational_crops()

vector<AlmassCrop> OptimisingFarm::Get_rotational_crops ( )
inline
2051 {return m_rotational_crops;};

References m_rotational_crops.

◆ Get_rotational_crops_visible()

vector<AlmassCrop> OptimisingFarm::Get_rotational_crops_visible ( )
inline
2052 {return m_rotational_crops_visible;};

References m_rotational_crops_visible.

Referenced by ChooseDecisionMode().

◆ Get_soilSubType()

int OptimisingFarm::Get_soilSubType ( void  )
inline
2038 {return m_soilSubType;}
int m_soilSubType
Farm's soil subtype. Defined only for cattle farms on sandy soil (0-bad, 1-good, 2-undefined).
Definition: farm.h:2218

References m_soilSubType.

◆ Get_soilType()

TTypesOfSoils OptimisingFarm::Get_soilType ( void  )
inline
2035 {return m_soilType;}

References m_soilType.

Referenced by Find_neighbour_to_imitate().

◆ GetFarmCentroidX()

int OptimisingFarm::GetFarmCentroidX ( )
inline
2055 { return m_farm_centroidx; }
int m_farm_centroidx
Farm's centroid, value x. Equal to the average of the x centroid values of all farm's fields.
Definition: farm.h:959

References Farm::m_farm_centroidx.

Referenced by FarmManager::FindNeighbours().

◆ GetFarmCentroidY()

int OptimisingFarm::GetFarmCentroidY ( )
inline
2056 { return m_farm_centroidy; }
int m_farm_centroidy
Farm's centroid, value y. Equal to the average of the y centroid values of all farm's fields.
Definition: farm.h:961

References Farm::m_farm_centroidy.

Referenced by FarmManager::FindNeighbours().

◆ HandleEvents()

void OptimisingFarm::HandleEvents ( void  )
protectedvirtual

If there are events to carry out do this, and perhaps start a new crop.

Call the management plan for the current crop and it this return done=true starts the next management.

Sets the new index to the rotation.

Save the new veg type as the LE vegetation type

Reimplemented from Farm.

952  {
953  if ( m_queue.Empty() )
954  return;
955 
957  FarmEvent * ev = pair.m_element;
958  while ( pair.m_pri <= g_date->Date() ) {
959  m_queue.Pop();
960 
961  if ( LeSwitch( ev ) ) {
962  // This crop management plan has terminated.
963 
964  // First check for an infinite loop in the rotation scheme,
965  // ie. a scenario where all crops decide not to run given
966  // the date.
968 
969  // Outdate any remaining events for this field.
970  ev->m_field->BumpRunNum();
971 
972  // Crop treatment done, select and initiate new crop if in rotation.
973  TTypesOfVegetation new_veg = ev->m_field->GetVegType();
974 
975  if ( ev->m_field->GetRotIndex() >= 0 ) {
976  int new_index = GetNextCropIndex( ev->m_field->GetRotIndex() );
977  new_veg = m_rotation[ new_index ];
978  // Running in fixed crop mode?
981  }
982  /*
983  if ( g_farm_test_crop.value() ) {
984  new_veg = g_letype->TranslateVegTypes( g_farm_test_crop_type.value() );
985  }
986  */
987  ev->m_field->SetRotIndex( new_index );
988  ev->m_field->SetVegType( new_veg, tov_Undefined );
989  // ***CJT*** Testing removal 3/2/2015 ev->m_field->ForceGrowthTest();
990  }
991 
992 
993  //------------05.03.12 AM - tell a field the crop has changed - here the OptimisingFarm part---------------------------------------
994  if(!cfg_OptimiseBedriftsmodelCrops.value()){ //don't do this if you simulate the bedriftsmodel (original farm optimization model) crops
995  //switch the previous crop (if it is still there) to position 1 in an array m_CropDataStorage; put a new crop at position 0
996  VegElement * pf = dynamic_cast<VegElement*>(ev->m_field);
997  if(pf->Get_taken(0)){ //there is a crop at position 0 - so need to copy it to position 1 and clear all values at position 0
998  if(pf->Get_taken(1)){ //problem - we have 3rd crop when two previous crops were not calculated yet - it shouldn't happen!
999  char error_num[ 20 ];
1000  sprintf( error_num, "%d", new_veg );
1001  g_msg->Warn( WARN_FILE, "Farm::HandleEvents(): there is 3rd crop starting when 2 previous were not calculated yet, the 3rd crop is", error_num );
1002  exit( 1 );
1003  }
1004  pf->Set_CropDataStorage(1, pf->Get_CropDataStorage(0)); //copy the content of a struct at position 0 of the m_CropDataStorage array to position 1
1005  pf->Set_taken(true, 1); //mark the struct at position 1 as taken by a crop
1006  pf->Clean_CropDataStorage(0); //clear struct at position 0
1007 
1008  }
1009  //now save the new crop at position zero - whether there was a crop here or not
1010  pf->Clean_CropDataStorage(0); //clear struct at position 0 //do it cause the previous crop's operations could have been saved here - if there was some time between accoutning and start of this new crop
1011  pf->Set_taken(true, 0); // the new crop is at position 0
1012  pf->Set_tov_type(new_veg, 0); //save the tov_type of a new crop
1013  pf->Set_area_in_crop_data(pf->GetArea());
1014  }
1015  //---------------------end 05.03.13----------------------------------------------------------------
1016 
1017 
1018  // Reset the event list for this field.
1019  ev->m_field->ResetTrace();
1020  // Reset event timeout counter.
1021  ev->m_field->SetVegStore( 0 );
1022 
1023  // The next bit simply determines the start date of the next crop in
1024  // the rotation and passes this to the start crop event.
1025  // The crop is responsible for raising an error if the next crop is
1026  // not possible or otherwise handling the problem
1027 
1028  // 19/5-2003: Note: This code was moved out into a dedicated
1029  // method of the Farm class, GetNextCropStartDate(), as precisely
1030  // the same piece of code needs to be run during initialization of
1031  // farm management.
1032  TTypesOfVegetation l_tov = new_veg;
1033  int l_nextcropstartdate = GetNextCropStartDate( ev->m_field, l_tov );
1034 
1035  // Create 'start' event for today and put it on the queue.
1036  AddNewEvent( new_veg, g_date->Date(), ev->m_field, PROG_START, ev->m_field->GetRunNum(), false, l_nextcropstartdate, false, l_tov );
1037 
1038  // Set starting date for rotation mgmt loop detection.
1040  }
1041 
1042  delete ev;
1043 
1044  if ( m_queue.Empty() )
1045  return;
1046  pair = m_queue.Bottom();
1047  ev = pair.m_element;
1048  }
1049 }
long Date(void)
Definition: calendar.h:57
int value(void)
Definition: configurator.h:98
bool LeSwitch(FarmEvent *ev)
Call do function for any crop with an outstanding event. Signal if the crop has terminated.
Definition: farm.cpp:386
void AddNewEvent(TTypesOfVegetation a_event, long a_date, LE *a_field, int a_todo, long a_num, bool a_lock, int a_start, bool a_first_year, TTypesOfVegetation a_crop)
Adds an event to the event queue for a farm.
Definition: farm.cpp:789
void CheckRotationManagementLoop(FarmEvent *ev)
Definition: farm.cpp:839
vector< TTypesOfVegetation > m_rotation
Definition: farm.h:938
virtual int GetNextCropIndex(int a_rot_index)
Returns the next crop in the rotation.
Definition: farm.cpp:1427
int GetNextCropStartDate(LE *a_field, TTypesOfVegetation &a_curr_veg)
Returns the start date of the next crop in the rotation.
Definition: farm.cpp:864
LowPriority< FarmEvent * > m_queue
Definition: farm.h:936
TTypesOfVegetation TranslateVegTypes(int VegReference)
Definition: elements.cpp:3088
double GetArea(void)
Definition: elements.h:196
int GetRotIndex(void)
Definition: elements.h:309
void ResetTrace(void)
Definition: elements.cpp:467
virtual void SetVegType(TTypesOfVegetation, TTypesOfVegetation)
Definition: elements.h:164
long GetRunNum(void)
Definition: elements.h:117
void SetRotIndex(int a_index)
Definition: elements.h:307
void SetMgtLoopDetectDate(long a_num)
Definition: elements.h:120
void BumpRunNum(void)
Definition: elements.h:118
void SetVegStore(int a_veg)
Definition: elements.h:127
virtual TTypesOfVegetation GetVegType(void)
Definition: elements.h:125
void Pop()
Definition: lowqueue.h:124
bool Empty(void)
Definition: lowqueue.h:129
LowPriPair< ELEMTYPE > Bottom(void)
Definition: lowqueue.h:134
void Set_taken(bool a_taken, int index)
Definition: elements.h:637
void Set_tov_type(TTypesOfVegetation a_tov_type, int index)
Definition: elements.h:639
void Set_CropDataStorage(int index, CropActualValues a_struct)
Definition: elements.h:662
void Set_area_in_crop_data(double a_area)
Definition: elements.h:641
class LE_TypeClass * g_letype
Definition: elements.cpp:277
#define PROG_START
Definition: farm.h:76
CfgInt g_farm_fixed_crop_type("FARM_FIXED_CROP_TYPE", CFG_CUSTOM, 22)
CfgBool g_farm_fixed_crop_enable("FARM_FIXED_CROP_ENABLE", CFG_CUSTOM, false)
A struct to hold the information required to trigger a farm event.
Definition: farm.h:464
LE * m_field
Definition: farm.h:472
Used in event handling.
Definition: lowqueue.h:84
ELEMTYPE m_element
Definition: lowqueue.h:88
long m_pri
Definition: lowqueue.h:89

References LE::BumpRunNum(), cfg_OptimiseBedriftsmodelCrops, VegElement::Clean_CropDataStorage(), Calendar::Date(), g_date, g_farm_fixed_crop_enable, g_farm_fixed_crop_type, g_letype, g_msg, VegElement::Get_CropDataStorage(), VegElement::Get_taken(), LE::GetArea(), LE::GetRotIndex(), LE::GetRunNum(), LE::GetVegType(), LowPriPair< ELEMTYPE >::m_element, FarmEvent::m_field, LowPriPair< ELEMTYPE >::m_pri, PROG_START, LE::ResetTrace(), VegElement::Set_area_in_crop_data(), VegElement::Set_CropDataStorage(), VegElement::Set_taken(), VegElement::Set_tov_type(), LE::SetMgtLoopDetectDate(), LE::SetRotIndex(), LE::SetVegStore(), LE::SetVegType(), tov_Undefined, LE_TypeClass::TranslateVegTypes(), CfgInt::value(), CfgBool::value(), MapErrorMsg::Warn(), and WARN_FILE.

◆ Harvest()

bool OptimisingFarm::Harvest ( LE a_field,
double  a_user,
int  a_days 
)
virtual

OptimisingFarm's virtual version of Farm::Harvest(). Saves information on biomass of a crop at harvest.

Reimplemented from Farm.

1860 {
1861 
1862  //5 days good weather before
1863  if ( (0 >= a_days) ||
1864  ((g_weather->GetRainPeriod(g_date->Date(),5)<0.1) && DoIt(DO_IT_PROB)))
1865  {
1866 
1867  //05.03.13 need to get the info on biomass
1869  Field * pf = dynamic_cast<Field*>(a_field); //ok????? - maybe should be VegElement instead of field!
1870  if(pf->GetVegType()!=tov_Potatoes && pf->GetVegType()!=tov_PotatoesIndustry){ //do not save biomass for potatoes!
1871  double biomass_at_harvest = a_field->GetVegBiomass();
1872  pf->Set_biomass_at_harvest(biomass_at_harvest, 0); //sets the biomass of a current crop; the current crop is at the index 0
1873  pf->Set_harvested(); //mark this crop as harvested
1874  }
1875  }
1876  //05.03.13 end
1877 
1878  a_field->Trace( harvest );
1879  a_field->SetLastTreatment( harvest );
1880  a_field->SetGrowthPhase( harvest1 );
1881  // Here we have to do a little skip to avoid too low insect populations after harvest, but a correct veg biomass
1882  a_field->InsectMortality( 0.4 );
1883  double insects=a_field->GetInsectPop();
1884  a_field->RecalculateBugsNStuff();
1885  a_field->SetInsectPop(insects);
1887  a_field->ResetDigestability();
1888  int pref=a_field->GetUnsprayedMarginPolyRef();
1889  if (pref!=-1){
1890  // Must have an unsprayed margin so need to pass the information on to it
1891  LE* um=g_landscape_p->SupplyLEPointer(pref);
1893  um->SetGrowthPhase( harvest1 );
1894  um->InsectMortality( 0.4 );
1896  um->ResetDigestability();
1897  um->RecalculateBugsNStuff();
1898  }
1899  return true;
1900  }
1901  return false;
1902 }
Definition: elements.h:81
virtual void RecalculateBugsNStuff(void)
Definition: elements.h:132
virtual double GetVegBiomass(void)
Definition: elements.h:154
virtual void ResetDigestability()
sets growth record to zero in descendent classes
Definition: elements.h:382
virtual void SetGrowthPhase(int)
Definition: elements.h:170
virtual double GetInsectPop(void)
Definition: elements.h:156
int GetUnsprayedMarginPolyRef(void)
Definition: elements.h:319
virtual void SetInsectPop(double)
Definition: elements.h:157
virtual void InsectMortality(double)
Definition: elements.h:159
LE * SupplyLEPointer(int a_polyref)
Definition: landscape.h:1099
void Set_harvested()
Definition: elements.h:644
void Set_biomass_at_harvest(double a_biomass, int index)
Definition: elements.h:642
virtual TTypesOfVegetation GetVegType(void)
Definition: elements.h:588
double GetRainPeriod(long a_date, unsigned int a_period)
Definition: weather.cpp:253
@ harvest1
Definition: plants.h:55
@ harvest
Definition: treatment.h:82

References cfg_OptimiseBedriftsmodelCrops, Calendar::Date(), DO_IT_PROB, EL_TRAMLINE_DECAYTIME, g_date, g_landscape_p, g_weather, LE::GetInsectPop(), Weather::GetRainPeriod(), LE::GetUnsprayedMarginPolyRef(), LE::GetVegBiomass(), VegElement::GetVegType(), harvest, harvest1, LE::InsectMortality(), LE::RecalculateBugsNStuff(), LE::ResetDigestability(), VegElement::Set_biomass_at_harvest(), VegElement::Set_harvested(), LE::SetGrowthPhase(), LE::SetInsectPop(), LE::SetLastTreatment(), LE::SetTramlinesDecay(), Landscape::SupplyLEPointer(), tov_Potatoes, tov_PotatoesIndustry, LE::Trace(), and CfgBool::value().

◆ HerbicideTreat()

bool OptimisingFarm::HerbicideTreat ( LE a_field,
double  ,
int  a_days 
)
protectedvirtual

Carries out herbicide application. Saves information on each application for a given crop.

Reimplemented from Farm.

1197 {
1198 
1199  if (0 >= a_days) // Must do this
1200  {
1201  if (((a_field->GetSignal() & LE_SIG_NO_HERBICIDE)==0 ))
1202  {
1203  a_field->Trace( herbicide_treat );
1204  a_field->SetLastTreatment( herbicide_treat );
1205  if ( l_farm_herbicide_kills.value()) {
1206  a_field->ReduceWeedBiomass( 0.05 );
1207  }
1211 
1212 
1214  Field * pf = dynamic_cast<Field*>(a_field);
1215  pf->Add_no_herb_app();
1216  }
1217 
1218  }
1219  return true;
1220  }
1221  else if ((g_weather->GetWind()<4.5) && (!g_weather->Raining()) && DoIt(DO_IT_PROB))
1222  {
1223  if ( !(a_field->GetSignal() & LE_SIG_NO_HERBICIDE) )
1224  {
1225  a_field->Trace( herbicide_treat );
1226  a_field->SetLastTreatment( herbicide_treat );
1227  if ( l_farm_herbicide_kills.value()) {
1228  a_field->ReduceWeedBiomass( 0.05 );
1229  }
1233 
1235  Field * pf = dynamic_cast<Field*>(a_field);
1236  pf->Add_no_herb_app();
1237  }
1238  }
1239  return true;
1240  }
1241  return false;
1242 }
virtual void ReduceWeedBiomass(double)
Definition: elements.h:160
void SetHerbicideDelay(int a_decaytime_days)
Definition: elements.h:312
void Add_no_herb_app()
Definition: elements.h:647
#define LE_SIG_NO_HERBICIDE
Definition: elements.h:47
#define EL_HERBICIDE_DELAYTIME
Definition: elements.h:60
static CfgBool l_farm_herbicide_kills("FARM_PESTICIDE_KILLS", CFG_CUSTOM, true)
@ herbicide
Definition: landscape.h:63
@ herbicide_treat
Definition: treatment.h:71

References VegElement::Add_no_herb_app(), cfg_OptimiseBedriftsmodelCrops, Landscape::CheckForPesticideRecord(), DO_IT_PROB, EL_HERBICIDE_DELAYTIME, EL_TRAMLINE_DECAYTIME, g_landscape_p, g_weather, LE::GetSignal(), Weather::GetWind(), herbicide, herbicide_treat, l_farm_herbicide_kills, LE_SIG_NO_HERBICIDE, Weather::Raining(), LE::ReduceWeedBiomass(), LE::SetHerbicideDelay(), LE::SetLastTreatment(), LE::SetTramlinesDecay(), LE::Trace(), and CfgBool::value().

◆ increaseCrops()

void OptimisingFarm::increaseCrops ( vector< CropSort cropsToIncrease,
double &  howMuchToIncrease 
)
protectedvirtual

Increases area of crops by a specified number.

Function increases area of one or more crops from the list given as a first argument.The total area added to the crops in the list is equal to the value of the second argument.

Reimplemented in AnimalFarm.

7854  {
7857  for(int i=0; howMuchToIncrease>0 && i<(int)cropsToIncrease.size(); i++){
7858  double area = cropsToIncrease[i].crop->m_areaPercent;
7859  double rotationMax = cropsToIncrease[i].crop->m_rotationMax;
7860  double rotMinCrop = cropsToIncrease[i].crop->m_rotationMin;
7861  if(area + howMuchToIncrease <= rotationMax){
7862  area += howMuchToIncrease; //finito
7863  howMuchToIncrease = 0;
7864  }
7865  else{
7866  howMuchToIncrease -= rotationMax-area;
7867  area = rotationMax;
7868  }
7869  cropsToIncrease[i].crop->m_areaPercent = area;
7870  cropsToIncrease[i].crop->m_areaVariable = area - rotMinCrop;
7871  }
7872 }

Referenced by NonAnimalFarm::checkWinterCrops(), and NonAnimalFarm::checkWinterRotation1().

◆ Init()

void OptimisingFarm::Init ( ofstream *  ap_output_file)

Function carrying out the initial calculations at a farm level (including the initial optimisation).

5294  {
5295 
5296  int foobar = (cfg_OptimiseBedriftsmodelCrops.value())? (int)toc_Foobar : (int)tov_Undefined;
5297 
5298  FarmLevelCalculation(); //could stay in the constructor, but for clarity should be here
5299  createCropsLists(foobar);
5300  OptimiseFarm(foobar);
5301  Print_FarmVariables(ap_output_file);
5302 
5305  Make_rotations();
5306  }
5307  else{ //need to create almass crop vector and do all the things that are done otherwise in Make_rotations
5310  m_rotation.push_back(tov_SpringBarley); //put there one crop for the hidden year - m_rotation is used to initialize
5311 
5312  //deal with perm crops (copied from make rotations):
5313  int area_perm = 0; //sum of areas of permanent crops
5314  int no_perm=0;
5315  for(int i = 0; i < (int)m_crops_almass.size(); i++){
5316  TTypesOfVegetation tov = m_crops_almass[i].Tov;
5317 
5319  tov==tov_PermanentGrassLowYield || tov==tov_YoungForest || tov==tov_OrchardCrop) { //|| tov==tov_Orchard
5320  int pct = (int)(m_crops_almass[i].Number + 0.5); //round a double to int
5321  PermCropData pcd = {tov, pct};
5322  m_PermCrops.push_back(pcd);
5323  no_perm++;
5324  area_perm += pct;
5325  }
5326  }
5327  }
5329  Print_rotations(ap_output_file);
5330  }
5331 
5332 }
vector< PermCropData > m_PermCrops
Definition: farm.h:939
void Make_rotations()
Creates m_rotation. Not used in ALMaSS crop mode.
Definition: farm.cpp:8403
void Print_rotations(ofstream *ap_output_file)
Prints the content of a farm's m_rotation. Not used in ALMaSS crop mode.
Definition: farm.cpp:8389
void FarmLevelCalculation()
Calls functions determining farm level values before the initial optimisation.
Definition: farm.cpp:5613
void Translate_crops_to_almass()
Translates crops from Bedriftsmodel (original farm optimization model) to Almass crops....
Definition: farm.cpp:8075
void Print_FarmVariables(ofstream *ap_output_file)
Prints farm-level variables to a text file (one file for all farms).
Definition: farm.cpp:8045
virtual void createCropsLists(int a_foobar)
Creates lists of crops.
Definition: farm.cpp:5570
vector< AlmassCrop > m_crops_almass
Vector of structs with almass type crops with positive areas in % (result of optimisation).
Definition: farm.h:2200
@ toc_Foobar
Definition: farm.h:367
Used for storing permanent crop data for the farm rotation.
Definition: farm.h:448
@ tov_PermanentSetaside
Definition: tov_declaration.h:49
@ tov_SpringBarley
Definition: tov_declaration.h:52

References cfg_OptimiseBedriftsmodelCrops, createCropsLists(), FarmLevelCalculation(), m_crops_almass, Farm::m_PermCrops, Farm::m_rotation, Make_almass_crops_vector(), Make_rotational_crops(), Make_rotations(), OptimiseFarm(), Print_FarmVariables(), Print_rotations(), toc_Foobar, tov_OrchardCrop, tov_PermanentGrassGrazed, tov_PermanentGrassLowYield, tov_PermanentGrassTussocky, tov_PermanentSetaside, tov_SpringBarley, tov_Undefined, tov_YoungForest, Translate_crops_to_almass(), and CfgBool::value().

Referenced by FarmManager::InitFarms().

◆ Initialize()

void OptimisingFarm::Initialize ( FarmManager a_pfm)
protected

Assigns to each farm its farm type, farm size, farm's real ID number, and soil type. It creates livestock and crops.

5187  {
5188 
5189  //assign to each farm: farm type, farm size, real ID and soil type + soil subtype
5190  int size=(int)a_pfm->pm_data->m_farm_data.size();
5191  for(int i=0; i<size; i++){
5192  if(m_almass_no==a_pfm->pm_data->m_farm_data[i]->md_almass_no){
5193  m_farmType=a_pfm->pm_data->m_farm_data[i]->md_farmType;
5194  m_farmSize=a_pfm->pm_data->m_farm_data[i]->md_farmSize;
5195  m_farmRealID=a_pfm->pm_data->m_farm_data[i]->md_farmRealID;
5196  m_soilType=a_pfm->pm_data->m_farm_data[i]->md_soilType;
5197  m_soilSubType=a_pfm->pm_data->m_farm_data[i]->md_soilSubType;
5198  }
5199  }
5200 
5201  //create livestock
5202  for(int i=0; i<toa_Foobar; i++){
5203  int index=-1;
5204  int livestocknum=a_pfm->pm_data->Get_livestockNumbersSize();
5205  int j;
5206  for(j=0; j<livestocknum; j += (toa_Foobar+1)){
5207  if((a_pfm->pm_data->Get_livestockNumber(j))==m_almass_no){
5208  index=j;
5209  }
5210  }
5211  //test for index!!
5212  if(index==-1){
5213  g_msg->Warn( WARN_BUG, "Farm's almass_no doesn't match any of the numbers within the livestock numbers vector", "" );
5214  exit(0);
5215  }
5216  int index2 = index + 1 + i;
5217  int number = a_pfm->pm_data->Get_livestockNumber(index2);
5218  if (number!=0){
5219  Livestock * p_lvs;
5220  TTypesOfAnimals livestock_type = a_pfm->pm_data->Get_livestockTypes(i);
5221  p_lvs = new Livestock(livestock_type, number);
5222  Set_Livestock(p_lvs);
5223  }
5224  }
5225 
5226  //create crops
5227  int no_crops = (cfg_OptimiseBedriftsmodelCrops.value())? toc_Foobar : a_pfm->pm_data->Get_noCrops(); //bedriftsmodel crops/almass crops
5228 
5229  for(int i=0; i<no_crops; i++){ //crop areas vector contains only the crops that are used, not all tov types!
5230  int index=-1;
5231  int croparea=a_pfm->pm_data->Get_cropAreasSize();
5232  int j;
5233  for(j=0; j<croparea; j+=(no_crops+1)){ //+1 becuase in the vector we store also farm numbers
5234  if((a_pfm->pm_data->Get_cropArea(j))==m_almass_no){
5235  index=j;
5236  break;
5237  }
5238  }
5239  //test for index!!
5240  if(index==-1){
5241  g_msg->Warn( WARN_BUG, "Farm's almass_no doesn't match any of the numbers within the crop areas vector", "" );
5242  exit(0);
5243  }
5244  int index2= index + 1 + i;
5245  double area=a_pfm->pm_data->Get_cropArea(index2);
5246 
5247  int foobar = (cfg_OptimiseBedriftsmodelCrops.value())? (int)toc_Foobar : (int)tov_Undefined; //bedriftsmodel crops/almass crops
5248 
5249  CropOptimised *p_crop;
5250  int index3 = -1;
5252  TTypesOfCrops crop_type = a_pfm->pm_data->Get_cropTypes(i);
5253  p_crop = new CropOptimised(crop_type, area);
5254  index3 = foobar*tofs_Foobar*tos_Foobar*m_farmType + foobar*tofs_Foobar*m_soilType + foobar*m_farmSize + crop_type; //crop_type is TTypesOfCrops
5255  }
5256  else{
5257  TTypesOfVegetation crop_type = a_pfm->pm_data->Get_cropTypes_almass(i);
5258  p_crop = new CropOptimised(crop_type, area);
5259  index3 = foobar*tofs_Foobar*tos_Foobar*m_farmType + foobar*tofs_Foobar*m_soilType + foobar*m_farmSize + crop_type; //crop_type is TTypesOfVegetation
5260  }
5261  //added 01.05: save the rot max ad min
5262  p_crop->m_rotationMax = m_OurManager->pm_data->Get_rotationMax(index3);
5263  p_crop->m_rotationMin = m_OurManager->pm_data->Get_rotationMin(index3);
5264 
5265  //add crop to the list of crops
5266  Set_Crop(p_crop);
5267  }
5268 }
int Get_cropAreasSize()
Definition: farm.h:608
int Get_livestockNumber(int index)
Definition: farm.h:605
int Get_livestockNumbersSize()
Definition: farm.h:606
double Get_rotationMin(int i)
Definition: farm.h:655
TTypesOfAnimals Get_livestockTypes(int i)
Definition: farm.h:598
TTypesOfCrops Get_cropTypes(int i)
Definition: farm.h:600
double Get_rotationMax(int i)
Definition: farm.h:653
double Get_cropArea(int index)
Definition: farm.h:607
vector< FarmData * > m_farm_data
Definition: farm.h:685
A class for storing livestock parameters and variables for optimising farms.
Definition: farm.h:1617
void Set_Crop(CropOptimised *p_crop)
Definition: farm.h:2043
void Set_Livestock(Livestock *p_lvs)
Definition: farm.h:2042
TTypesOfCrops
Definition: farm.h:323
@ tofs_Foobar
Definition: farm.h:296
@ toa_Foobar
Definition: farm.h:320

References cfg_OptimiseBedriftsmodelCrops, g_msg, DataForOptimisation::Get_cropArea(), DataForOptimisation::Get_cropAreasSize(), DataForOptimisation::Get_cropTypes(), DataForOptimisation::Get_cropTypes_almass(), DataForOptimisation::Get_livestockNumber(), DataForOptimisation::Get_livestockNumbersSize(), DataForOptimisation::Get_livestockTypes(), DataForOptimisation::Get_noCrops(), DataForOptimisation::Get_rotationMax(), DataForOptimisation::Get_rotationMin(), m_almass_no, DataForOptimisation::m_farm_data, m_farmRealID, m_farmSize, m_farmType, Farm::m_OurManager, CropOptimised::m_rotationMax, CropOptimised::m_rotationMin, m_soilSubType, m_soilType, FarmManager::pm_data, Set_Crop(), Set_Livestock(), toa_Foobar, toc_Foobar, tofs_Foobar, tos_Foobar, tov_Undefined, CfgBool::value(), MapErrorMsg::Warn(), and WARN_BUG.

Referenced by OptimisingFarm().

◆ InitiateManagement()

void OptimisingFarm::InitiateManagement ( void  )
protectedvirtual

Kicks off the farm's management.

It assignes permanent crops (if there are any) to fields. In case there are no rotational crops it checks if there are any fields that haven't been assigned any permanent crop. In case there are, it assignes to a field a first permanent crop from the list of this farm's permanent crops.

Reimplemented from Farm.

5124  {
5125 
5130  // First we need to assign the permanent crops if any.
5131  if (m_PermCrops.size()>0) {
5132  // We have something to do
5133  for (int i=0; i<(int)m_PermCrops.size(); i++) {
5135  }
5136 
5137  //check if in case there are no rotational crops - all fields have been assigned a perm crop
5138  if(m_area_rot ==0) { //so there's need to check
5139  for(int i=0; i<(int)m_fields.size(); i++){
5140  if(m_fields[i]->GetRotIndex() != -4){ //there is a field that is not assigned a perm crop!
5141  m_fields[i]->SetRotIndex(-4);
5142  TTypesOfVegetation tov = m_PermCrops[0].Tov; //just take the first perm crop?
5143  m_fields[i]->SetVegType(tov, tov_Undefined); //need a tov of one of the assigned perm crops
5144  }
5145  }
5146  }
5147 
5148  }
5149 
5151 }
virtual void InitiateManagement(void)
Kicks off the farm's management.
Definition: farm.cpp:1514
void AssignPermanentCrop(TTypesOfVegetation tov, int pct)
Used to assign a permanent crop to an otherwise rotational field polygon.
Definition: farm.cpp:2401
double m_area_rot
Area assigned to rotational crops. [ha].
Definition: farm.h:2266

References Farm::AssignPermanentCrop(), Farm::InitiateManagement(), m_area_rot, Farm::m_fields, Farm::m_PermCrops, and tov_Undefined.

◆ InsecticideTreat()

bool OptimisingFarm::InsecticideTreat ( LE a_field,
double  ,
int  a_days 
)
protectedvirtual

Carries out insecticide application. Saves information on each application for a given crop.

Reimplemented from Farm.

1390 {
1391 
1392  if (0 >= a_days)
1393  {
1394  if (( ! (a_field->GetSignal() & LE_SIG_NO_INSECTICIDE) ))
1395  {
1396  // **CJT** Turn this code on to use the pesticide engine with insecticides
1397  // g_pest->DailyQueueAdd( a_field, l_pest_insecticide_amount.value());
1398  //
1399  a_field->Trace( insecticide_treat );
1400  a_field->SetLastTreatment( insecticide_treat );
1402  a_field->Insecticide( 0.36 );
1403  }
1406 
1408  Field * pf = dynamic_cast<Field*>(a_field);
1409  pf->Add_no_fi_app();
1410  }
1411 
1412  }
1413  return true;
1414  }
1415  else if ( (g_weather->GetWind()<4.5) && (!g_weather->Raining()) && DoIt(DO_IT_PROB))
1416  {
1417  if ( ! (a_field->GetSignal() & LE_SIG_NO_INSECTICIDE )) {
1418  // **CJT** Turn this code on to use the pesticide engine with insecticides
1419  // g_pest->DailyQueueAdd( a_field, l_pest_insecticide_amount.value());
1420  //
1421  a_field->Trace( insecticide_treat );
1422  a_field->SetLastTreatment( insecticide_treat );
1424  a_field->Insecticide( 0.36 );
1425  }
1428 
1430  Field * pf = dynamic_cast<Field*>(a_field);
1431  pf->Add_no_fi_app();
1432  }
1433  }
1434 
1435  return true;
1436  }
1437  return false;
1438 }
virtual void Insecticide(double)
Definition: elements.h:158
#define LE_SIG_NO_INSECTICIDE
Definition: elements.h:43
static CfgBool l_farm_insecticide_kills("FARM_INSECTICIDE_KILLS", CFG_CUSTOM, true)
@ insecticide
Definition: landscape.h:63
@ insecticide_treat
Definition: treatment.h:74

References VegElement::Add_no_fi_app(), cfg_OptimiseBedriftsmodelCrops, Landscape::CheckForPesticideRecord(), DO_IT_PROB, EL_TRAMLINE_DECAYTIME, g_landscape_p, g_weather, LE::GetSignal(), Weather::GetWind(), LE::Insecticide(), insecticide, insecticide_treat, l_farm_insecticide_kills, LE_SIG_NO_INSECTICIDE, Weather::Raining(), LE::SetLastTreatment(), LE::SetTramlinesDecay(), LE::Trace(), and CfgBool::value().

◆ Make_almass_crops_vector()

void OptimisingFarm::Make_almass_crops_vector ( )
protected

Creates a vector storing crops with positive area. Used in ALMaSS crop mode.

The function goes throught the list of all crops and attach them to the m_crops_almass vector if the area resulting from optimisation is larger than zero.

8269  {
8273  m_crops_almass.clear();
8274 
8275  for(int i = 0; i < (int)m_crops.size(); i++){
8276  if(m_crops[i]->m_areaPercent > 0){
8277  TTypesOfVegetation tov = m_crops[i]->m_cropType_almass;
8278  AlmassCrop crop = { m_crops[i]->m_areaPercent, tov};
8279  m_crops_almass.push_back(crop);
8280  }
8281  }
8282 
8283 }
Struct for storing ALMaSS crop type (TTypesOfVegetation) with a corresponding value (mainly crop area...
Definition: farm.h:580

References m_crops, and m_crops_almass.

Referenced by ChooseDecisionMode(), and Init().

◆ Make_rotational_crops()

void OptimisingFarm::Make_rotational_crops ( )
protected

Creates a vector m_rotational_crops using the results of optimisation.

8285  {
8286 
8287  //first deal with the probelmatic crops:CGG1 + CGG2 and SB, and SG1 + SG2
8288  double area_cgg=0;
8289  for(int i = 0; i < (int)m_crops_almass.size(); i++){
8290  if(m_crops_almass[i].Tov == tov_CloverGrassGrazed1){
8291  bool cg2=false;
8292  for(int j = 0; j < (int)m_crops_almass.size(); j++){
8293  if(m_crops_almass[j].Tov == tov_CloverGrassGrazed2){
8294  double pct = (m_crops_almass[i].Number + m_crops_almass[j].Number)/2; //take average
8295  m_crops_almass[i].Number = pct;
8296  m_crops_almass[j].Number = pct;
8297  area_cgg = pct;
8298  cg2=true;
8299  }
8300  }
8301  if(!cg2){ //there is cgg1 but not cgg2
8302  double pct = (m_crops_almass[i].Number)/2; //divide cgg1 area by two and save it in cgg1 and create cgg2
8303  m_crops_almass[i].Number = pct;
8304  area_cgg = pct;
8305  AlmassCrop cgg2 = {pct, tov_CloverGrassGrazed2};
8306  m_crops_almass.push_back(cgg2);
8307  }
8308  break;
8309  }
8310  }
8311 
8312  //cgg and sb
8313  bool sb=false;
8314  double new_area = area_cgg; //initialize with the current area of cgg - maybe it won't change
8315  for(int i = 0; i < (int)m_crops_almass.size(); i++){
8316  if(m_crops_almass[i].Tov == tov_SpringBarley){
8317  sb=true;
8318  double area_sb = m_crops_almass[i].Number;
8319  if(area_sb < area_cgg){ //problem
8320  new_area = (area_sb + 2*area_cgg)/3;
8321  m_crops_almass[i].Number = new_area;
8322  }
8323  break;
8324  }
8325  }
8326  if(!sb){ //there wasn't spring barley - need to add
8327  new_area = area_cgg*2/3;
8328  if(new_area >0){ //otherwise do not add sbarley
8329  AlmassCrop sbarley = {new_area, tov_SpringBarley};
8330  m_crops_almass.push_back(sbarley);
8331  }
8332  }
8333  //now find both cgg and change their areas
8334  for(int j = 0; j < (int)m_crops_almass.size(); j++){
8335  if(m_crops_almass[j].Tov == tov_CloverGrassGrazed1){
8336  m_crops_almass[j].Number = new_area;
8337  }
8338  if(m_crops_almass[j].Tov == tov_CloverGrassGrazed2){
8339  m_crops_almass[j].Number = new_area;
8340  }
8341  }
8342 
8343 
8344 
8345  //sg1 and sg2
8346  for(int i = 0; i < (int)m_crops_almass.size(); i++){
8347  if(m_crops_almass[i].Tov == tov_SeedGrass1){
8348  bool sg2=false;
8349  for(int j = 0; j < (int)m_crops_almass.size(); j++){
8350  if(m_crops_almass[j].Tov == tov_SeedGrass2){
8351  double pct = (m_crops_almass[i].Number + m_crops_almass[j].Number)/2; //take average
8352  m_crops_almass[i].Number = pct;
8353  m_crops_almass[j].Number = pct;
8354  sg2=true;
8355  }
8356  }
8357  if(!sg2){ //there is cgg1 but not cgg2
8358  double pct = (m_crops_almass[i].Number)/2; //divide cgg1 area by two and save it in cgg1 and create cgg2
8359  m_crops_almass[i].Number = pct;
8360  AlmassCrop sgrass2 = {pct, tov_SeedGrass2};
8361  m_crops_almass.push_back(sgrass2);
8362  }
8363  break;
8364  }
8365  }
8366 
8367  //first clear the current m_rotational_crops
8368  m_rotational_crops.clear();
8369 
8370  //then add rotational crops from the list of all crops - both rotational and permanent
8371  m_area_rot = 0;//sum of areas of rotational crops - need it for checking if there is any field without perm crops in case there are no rot. crops
8372  for(int i = 0; i < (int)m_crops_almass.size(); i++){
8373  TTypesOfVegetation tov = m_crops_almass[i].Tov;
8374 
8377  //do nothing - just need rotational crops
8378  }
8379  else {
8380  double pct = m_crops_almass[i].Number;
8381  if(pct<0.5) pct+=0.5; //thanks to that such crop won't disappear! (won't have area=0 after rounding)
8382  AlmassCrop pcd = {pct, tov};
8383  m_rotational_crops.push_back(pcd);
8384  m_area_rot += pct;
8385  }
8386  }
8387 }

References m_area_rot, m_crops_almass, m_rotational_crops, tov_CloverGrassGrazed1, tov_CloverGrassGrazed2, tov_OrchardCrop, tov_PermanentGrassGrazed, tov_PermanentGrassLowYield, tov_PermanentGrassTussocky, tov_PermanentSetaside, tov_SeedGrass1, tov_SeedGrass2, tov_SpringBarley, and tov_YoungForest.

Referenced by ChooseDecisionMode(), and Init().

◆ Make_rotations()

void OptimisingFarm::Make_rotations ( )
protected

Creates m_rotation. Not used in ALMaSS crop mode.

Used in the Bedriftsmodel crop mode. The function provides the functionality of the UserDefinedFarm's constructor:

  • it assigns true or false to the variable Farm::m_stockfarmer
  • creates a vector of permanent crops
  • creates a vector of rotational crops, m_rotation vector (size equal 100 or 0 in case there are only permanent crops) with a number of crop ocurrences corresponding to the optimised crop areas in percent of the total farm area.
8403  {
8411  //1. STOCK FARM
8413  else m_stockfarmer = false;
8414 
8415  //2. INTENSITY - skip
8416 
8417  //3. PERMANENT vs ROTATIONAL CROPS
8418  //sort them and put into two vectors: m_PermCrops (member of Farm class, type: struct PermCropData) + local vector rotational_crops (type: struct AlmassCrop)
8419 
8420  int no_perm = 0;
8421  int no_rotational = 0;
8422  int area_perm = 0; //sum of areas of permanent crops
8423  m_area_rot = 0; //sum of areas of rotational crops
8424 
8425  for(int i = 0; i < (int)m_crops_almass.size(); i++){
8426  TTypesOfVegetation tov = m_crops_almass[i].Tov;
8427 
8430  int pct = (int)(m_crops_almass[i].Number + 0.5); //round a double to int
8431  PermCropData pcd = {tov, pct};
8432  m_PermCrops.push_back(pcd);
8433  no_perm++;
8434  area_perm += pct;
8435  }
8436  else {
8437  double pct = m_crops_almass[i].Number;
8438  if(pct<0.5) pct+=0.5; //thanks to that such crop won't disappear! (won't have area=0 after rounding)
8439  AlmassCrop pcd = {pct, tov};
8440  m_rotational_crops.push_back(pcd);
8441  no_rotational++;
8442  m_area_rot += pct;
8443  }
8444  }
8445 
8446  //4. ROTATIONAL CROPS
8447 
8448  //first check if there are any rotational crops!
8449  if(m_rotational_crops.size()!=0){
8450 
8451  m_rotation.resize(100);
8452  vector<TTypesOfVegetation>all_crops; //vector the has a right proportion of each crop tov type
8453  vector<MakeRotation>rotation;
8454  rotation.resize(100);
8455 
8456  //scale the rotational crop areas to account for the area that is reserved for permanent crops
8457  //and
8458  //save scaled areas of SBarley and CGG1 to make a check in the next step
8459  int area_rot_int = (int)(m_area_rot + 0.5); //area in percent of rot crops - as an integer
8460  int SBarley_area=0;
8461  int CGG1_area=0;
8462 
8463  for(int i=0; i<(int)m_rotational_crops.size(); i++){
8464  double area = m_rotational_crops[i].Number;
8465  int area_scaled = (int)(100 * area / area_rot_int + 0.5);
8466  m_rotational_crops[i].Number = area_scaled;
8467  if(m_rotational_crops[i].Tov == tov_CloverGrassGrazed1) CGG1_area = (int) m_rotational_crops[i].Number; //scaled area
8468  if(m_rotational_crops[i].Tov == tov_SpringBarley) SBarley_area = (int) m_rotational_crops[i].Number; //(this is scaled area)
8469  }
8470 
8471  //check if we have enough spring barley for CGG1 and CGG2 (area CGG1 = area CGG2); if not - change the areas so that
8472  //SBarley = CGG1 = CGG2 area.
8473  if(SBarley_area < CGG1_area){ //problem
8474  if(SBarley_area == 0){ //there's no sbarley! - need to create
8475  AlmassCrop sbarley = {0, tov_SpringBarley};
8476  m_rotational_crops.push_back(sbarley); //add sbarley
8477  }
8478  int new_area = (int)((CGG1_area * 2 + SBarley_area)/3 + 0.5); //= (CGG1 + CGG2 + SBarley)/3 ->and take integer
8479  for(int i=0; i<(int)m_rotational_crops.size(); i++){
8482  m_rotational_crops[i].Number = new_area;
8483  }
8484  }
8485  }
8486 
8487 
8488  //fill the all_crops vector with tov types -> in the right proportions
8489  for(int i = 0; i<(int)m_rotational_crops.size(); i++){
8490  int area = (int) m_rotational_crops[i].Number; //conversion to int - OK! - this is already int after the previous for loop
8491  for(int j = 0; j<area; j++){
8492  all_crops.push_back(m_rotational_crops[i].Tov);
8493  }
8494  }//now the size of all_crops might NOT be 100! - so check and make it to be 100?
8495 
8496  //sort the all_crops vector and rearrange it so that the probability of two crops that cannot follow each other is minimised
8497  //so - the order of the for loops below matter!!!
8498  vector<TTypesOfVegetation>all_crops_helper; //vector helper
8499 
8500  for(int i = (int)all_crops.size()-1; i>=0; i--){
8501  if(all_crops[i] == tov_SpringBarley) {
8502  all_crops_helper.push_back(all_crops[i]);
8503  all_crops.erase(all_crops.begin() + i);
8504  }
8505  }
8506 
8507  for(int i = (int)all_crops.size()-1; i>=0; i--){
8508  if(all_crops[i] == tov_CloverGrassGrazed1) {
8509  all_crops_helper.push_back(all_crops[i]);
8510  all_crops.erase(all_crops.begin() + i);
8511  }
8512  }
8513  for(int i = (int)all_crops.size()-1; i>=0; i--){
8514  if(all_crops[i] == tov_CloverGrassGrazed2) {
8515  all_crops_helper.push_back(all_crops[i]);
8516  all_crops.erase(all_crops.begin() + i);
8517  }
8518  }
8519  for(int i = (int)all_crops.size()-1; i>=0; i--){
8520  if(all_crops[i] == tov_FodderBeet) {
8521  all_crops_helper.push_back(all_crops[i]);
8522  all_crops.erase(all_crops.begin() + i);
8523  }
8524  }
8525  for(int i = (int)all_crops.size()-1; i>=0; i--){
8526  if(all_crops[i] == tov_WinterRape) {
8527  all_crops_helper.push_back(all_crops[i]);
8528  all_crops.erase(all_crops.begin() + i);
8529  }
8530  }
8531  for(int i = (int)all_crops.size()-1; i>=0; i--){
8532  if(all_crops[i] == tov_SpringRape) {
8533  all_crops_helper.push_back(all_crops[i]);
8534  all_crops.erase(all_crops.begin() + i);
8535  }
8536  }
8537  for(int i = (int)all_crops.size()-1; i>=0; i--){
8538  if(all_crops[i] == tov_Potatoes) {
8539  all_crops_helper.push_back(all_crops[i]);
8540  all_crops.erase(all_crops.begin() + i);
8541  }
8542  }
8543  for(int i = (int)all_crops.size()-1; i>=0; i--){
8544  if(all_crops[i] == tov_SeedGrass1) {
8545  all_crops_helper.push_back(all_crops[i]);
8546  all_crops.erase(all_crops.begin() + i);
8547  }
8548  }
8549  for(int i = 0; i<(int)all_crops.size(); i++){
8550  if(all_crops[i] == tov_SeedGrass2) {
8551  all_crops_helper.push_back(all_crops[i]);
8552  all_crops.erase(all_crops.begin() + i);
8553  }
8554  }
8555  for(int i = (int)all_crops.size()-1; i>=0; i--){
8556  if(all_crops[i] == tov_FieldPeas) {
8557  all_crops_helper.push_back(all_crops[i]);
8558  all_crops.erase(all_crops.begin() + i);
8559  }
8560  }
8561  for(int i = (int)all_crops.size()-1; i>=0; i--){
8562  if(all_crops[i] == tov_FieldPeasSilage) {
8563  all_crops_helper.push_back(all_crops[i]);
8564  all_crops.erase(all_crops.begin() + i);
8565  }
8566  }
8567  for(int i = (int)all_crops.size()-1; i>=0; i--){
8568  if(all_crops[i] == tov_WinterBarley) {
8569  all_crops_helper.push_back(all_crops[i]);
8570  all_crops.erase(all_crops.begin() + i);
8571  }
8572  }
8573  for(int i = (int)all_crops.size()-1; i>=0; i--){
8574  if(all_crops[i] == tov_WinterWheat) {
8575  all_crops_helper.push_back(all_crops[i]);
8576  all_crops.erase(all_crops.begin() + i);
8577  }
8578  }
8579  for(int i = (int)all_crops.size()-1; i>=0; i--){
8580  if(all_crops[i] == tov_Setaside) {
8581  all_crops_helper.push_back(all_crops[i]);
8582  all_crops.erase(all_crops.begin() + i);
8583  }
8584  }
8585 
8586  for(int i = (int)all_crops.size()-1; i>=0; i--){
8587  if(all_crops[i] == tov_MaizeSilage) {
8588  all_crops_helper.push_back(all_crops[i]);
8589  all_crops.erase(all_crops.begin() + i);
8590  }
8591  }
8592 
8593  //now place the other - remaining crops (in the all_crops vector) in further positions of the helper vector
8594  for(int i = 0; i<(int)all_crops.size(); i++){
8595  all_crops_helper.push_back(all_crops[i]);
8596  }
8597 
8598  //check if the size is 100 - correct if not
8599  if(all_crops_helper.size()!=100){
8600  if(all_crops_helper.size()>100){
8601  for(int i = (int)all_crops_helper.size(); i>100; i--){
8602  all_crops_helper.erase(all_crops_helper.end()-1); //just remove the last element
8603  }
8604  }
8605  else{ //<100
8606  for(int i = (int)all_crops_helper.size(); i<100; i++){
8607  if(all_crops_helper[i-2] != tov_CloverGrassGrazed2) all_crops_helper.push_back(all_crops_helper[i-2]); //this way I duplicate the ending (max 2/4 last elements)
8608  else all_crops_helper.push_back(tov_SpringBarley); //add spring barley
8609  }
8610  }
8611  }
8612 
8613  //copy the helper to all_crops
8614  all_crops = all_crops_helper;
8615 
8616 
8617  //fill the rotation vector with tov_Undefined
8618  for(int i = 0; i<(int)rotation.size(); i++){
8619  rotation[i].Tov = tov_Undefined;
8620  }
8621 
8622 
8623  // go through all_crops - should be 100...
8624 
8625  for(int i = 0; i < (int)all_crops.size(); i++){
8626 
8627  //find a place for the tov in the rotation vector:
8628  bool test=false;
8629  int count=0;
8630  TTypesOfVegetation crop_index = all_crops[i]; //current crop (tov) you want to place in a vector
8631 
8632  int step=no_rotational;
8633  int pp=0;
8634 
8635  for(int j = pp; count<101 && test==false; j=j+step){
8636  double sb_area = (cfg_OptimiseBedriftsmodelCrops.value())? findCropByName ("SBarley")->m_areaPercent : findCropByName_almass ("SpringBarley")->m_areaPercent;
8637  if (crop_index == tov_SpringBarley && sb_area > (100/step)) step = (int)(100/sb_area + 0.5);
8638  if(j>=100) {//without this we would always start out in the same position
8639  if (crop_index == tov_SpringBarley) {pp+=3; j=pp;} //special case - sbarley, cgg1 and cgg2; has to be 3 - doesn't work with 4
8640  else j=++pp;
8641  }
8642 
8643  if(!(rotation[j].taken)){ //not taken - so check if it is allowed here - lookup
8644 
8645  TTypesOfVegetation crop_before, crop_after;
8646 
8647  crop_before = (j==0) ? rotation[99].Tov : rotation[j-1].Tov;
8648  crop_after = (j==99) ? rotation[0].Tov : rotation[j+1].Tov;
8649 
8650  int lookup_before = m_OurManager->Get_lookup_table(crop_before * (tov_Undefined+1) + crop_index); //check with a preceeding crop; tov_undef+1 - because this tov_undef is included in the lookup table
8651  int lookup_after = m_OurManager->Get_lookup_table(crop_index * (tov_Undefined+1) + crop_after); //check with a following crop
8652 
8653  if(lookup_before==-1 || lookup_after==-1){ //issue a warning: wrong index...
8654  char index[ 20 ];
8655  sprintf( index, "%d", crop_index);
8656  g_msg->Warn( WARN_BUG, "OptimisingFarm::Make_rotations(): Error (possibly caused by a new tov type that is not incuded in the crops_lookup table) in reading the lookup table; tov type that should not appear: ", index );
8657  exit( 1 );
8658  }
8659 
8660  if(lookup_before==1 && lookup_after==1){
8661  rotation[j].Tov = all_crops[i]; //same as crop_index
8662  rotation[j].taken = true;
8663  test=true;
8664  }
8665  else count++; //did not succeed in placing the crop, so increase the count
8666  }
8667  else{
8668  count++; //did not succeed in placing the crop, so increase the count
8669  }
8670 
8671  } //inner for loop: searching for a place for a given crop
8672 
8673  if(test==false){ //there is no place that does not break the lookup table rules
8674 
8675  //so try to go through the whole rotation and find a place where the current crop fits
8676 
8677  for(int r=0; r<(int)rotation.size() && test==false; r++){
8678 
8679  TTypesOfVegetation crop_before, crop_after;
8680 
8681  crop_before = rotation[r].Tov;
8682  crop_after = (r==99) ? rotation[0].Tov : rotation[r+1].Tov;
8683  int lookup_before = m_OurManager->Get_lookup_table(crop_before * (tov_Undefined+1) + crop_index); //check with a preceeding crop; tov_undef+1 - because this tov_undef is included in the lookup table
8684  int lookup_after = m_OurManager->Get_lookup_table(crop_index * (tov_Undefined+1) + crop_after); //check with a following crop
8685 
8686  if(lookup_before==1 && lookup_after==1){
8687  MakeRotation crop = {true, all_crops[i]};
8688  rotation.insert(rotation.begin() + r+1, crop); //->insert before element r+1
8689  test=true;
8690 
8691  //need to remove 1 element of the rotation! as 1 additional was just inserted
8692  //but this might cause troubles: two already placed elements might become incompatible...
8693 
8694  for(int p=(int)rotation.size()-1; p>=0; p--){//start at the end - more efficient, as here should be empty elements
8695  if(rotation[p].Tov == tov_Undefined){
8696  rotation.erase(rotation.begin() + p);
8697  //check if the 'new neighbours' can be next to each other
8698  crop_before = (p==0) ? rotation[99].Tov : rotation[p-1].Tov;
8699  crop_after = (p==100) ? rotation[0].Tov : rotation[p].Tov; //100 because the index is p
8700  int crop_after_position = (p==100) ? 0 : p;
8701 
8702  lookup_before = m_OurManager->Get_lookup_table(crop_before * (tov_Undefined+1) + crop_after); //check with a preceeding crop; tov_undef+1 - because this tov_undef is included in the lookup table
8703 
8704  TTypesOfVegetation crop_before1, crop_after1, crop_before2;
8705  crop_before2=tov_Undefined; //for the begininng
8706  int crop_before2_position = 0; // **CJT** Added to remove warning 09-08-2018
8707  int count2=0;
8708 
8709  while(lookup_before!=1){ //need to move somewhere the crop_after
8710 
8711  //check if there is no correct rotation possible
8712  if(count2>100){ //problem: impossible to make a rotation
8713  //so switch some crop...to Spring Barley
8714  TTypesOfVegetation problem_crop = rotation[crop_before2_position].Tov;
8715  rotation[crop_before2_position].Tov = tov_SpringBarley;
8716  //issue a message
8717  char index[ 20 ];
8718  sprintf( index, "%d", problem_crop);
8719  g_msg->Warn( WARN_BUG, "OptimisingFarm::Make_rotations(): The following crop was changed to spring barley: ", index );
8720  break; //break the if
8721  }
8722 
8723  crop_index = crop_after; //now crop_after is searching for a place
8724  bool test2=false;
8725  for(int t=0; t<(int)rotation.size() && test2==false; t++){
8726  crop_before1 = rotation[t].Tov;
8727  crop_after1 = (t==99) ? rotation[0].Tov : rotation[t+1].Tov;
8728  int lookup_before1 = m_OurManager->Get_lookup_table(crop_before1 * (tov_Undefined+1) + crop_index); //check with a preceeding crop; tov_undef+1 - because this tov_undef is included in the lookup table
8729  int lookup_after1 = m_OurManager->Get_lookup_table(crop_index * (tov_Undefined+1) + crop_after1); //check with a following crop
8730 
8731  if(lookup_before1==1 && lookup_after1==1){
8732  //check for indefinite loop
8733 
8734  bool skip=true;
8735  for(int s=crop_after_position; s!=t+1; s++){ //check locations between;
8736  if(s==100) s=0;
8737  TTypesOfVegetation crop = rotation[s].Tov;
8738  int lookup = m_OurManager->Get_lookup_table(crop_before2 * (tov_Undefined+1) + crop);
8739  if( lookup == 1){
8740  skip = false;
8741  break; //there is a different crop that the one that we removed (crop_index) - so there shouldnt be an infinite loop
8742  }
8743  }
8744 
8745  if(!skip){
8746 
8747  MakeRotation crop = {true, crop_index};
8748  rotation.insert(rotation.begin() + t+1, crop);
8749  //now the crop to be removed can be at the same or changed position, depending on where we inserted the crop
8750 
8751  if(t+1 > crop_after_position){ //OK
8752  rotation.erase(rotation.begin() + crop_after_position); //remove the crop that was just placed in a new position-from the old one
8753  crop_before2 = (crop_after_position==0) ? rotation[99].Tov : rotation[crop_after_position-1].Tov;
8754  crop_before2_position = (crop_after_position==0) ? 99 : crop_after_position-1;
8755  crop_after = (crop_after_position==99) ? rotation[0].Tov : rotation[crop_after_position].Tov;
8756  crop_after_position = (crop_after_position==99) ? 0 : crop_after_position;
8757  lookup_before = m_OurManager->Get_lookup_table(crop_before2 * (tov_Undefined+1) + crop_after);
8758  }
8759  else{
8760  rotation.erase(rotation.begin() + crop_after_position + 1); //can be 99+1 -ok, now the size is 101
8761  crop_before2 = (crop_after_position==0) ? rotation[99].Tov : rotation[crop_after_position].Tov;
8762  crop_before2_position = (crop_after_position==0) ? 99 : crop_after_position;
8763  crop_after = (crop_after_position==99) ? rotation[0].Tov : rotation[crop_after_position+1].Tov;
8764  crop_after_position = (crop_after_position==99) ? 0 : crop_after_position+1;
8765  lookup_before = m_OurManager->Get_lookup_table(crop_before2 * (tov_Undefined+1) + crop_after);
8766  }
8767  test2=true;
8768  }
8769 
8770  }
8771 
8772  }
8773  count2++;
8774  } //while
8775 
8776  break; //break the for (index p) loop, need to remove just one element
8777  }//undefined removed
8778  }//for:searching for an undef element to remove
8779  }//if:found a place to put an element that doesnt fit in any empty space left
8780  }//for: searching for a place for a problematic crop
8781 
8782  if(test==false){ //we have a problem
8783  char index[ 20 ];
8784  sprintf( index, "%d", crop_index);
8785  //sprintf( index, "%d", m_almass_no);
8786  g_msg->Warn( WARN_BUG, "OptimisingFarm::Make_rotations(): The following tov type cannot be assigned a place in the rotation: ", index );
8787  exit( 1 );
8788  }
8789 
8790  }//there's no empty space that fits for the current crop
8791  }//outer for loop: searcin for an empty spae for a current crop
8792 
8793 
8794  //copy the tovs from rotation vector to the m_rotation vector
8795  for(int i=0; i<100; i++){
8796  m_rotation[i] = rotation[i].Tov;
8797  }
8798 
8799  }//if there are any rotational crops
8800 
8801 else{ //no rotational crops
8802  m_rotation.resize(0);
8803  }
8804 }
bool m_stockfarmer
Definition: farm.h:943
int Get_lookup_table(int index)
Definition: farm.h:1879
@ tov_FieldPeasSilage
Definition: tov_declaration.h:65
@ tov_WinterRape
Definition: tov_declaration.h:53
@ tov_FieldPeas
Definition: tov_declaration.h:34
@ tov_WinterWheat
Definition: tov_declaration.h:55
@ tov_SpringRape
Definition: tov_declaration.h:53
@ tov_MaizeSilage
Definition: tov_declaration.h:62
@ tov_Setaside
Definition: tov_declaration.h:50
@ tov_WinterBarley
Definition: tov_declaration.h:53

References cfg_OptimiseBedriftsmodelCrops, findCropByName(), findCropByName_almass(), g_msg, FarmManager::Get_lookup_table(), m_area_rot, CropOptimised::m_areaPercent, m_crops_almass, m_farmType, Farm::m_OurManager, Farm::m_PermCrops, Farm::m_rotation, m_rotational_crops, Farm::m_stockfarmer, toof_Cattle, toof_Pig, OptimisingFarm::MakeRotation::Tov, tov_CloverGrassGrazed1, tov_CloverGrassGrazed2, tov_FieldPeas, tov_FieldPeasSilage, tov_FodderBeet, tov_MaizeSilage, tov_OrchardCrop, tov_PermanentGrassGrazed, tov_PermanentGrassLowYield, tov_PermanentGrassTussocky, tov_PermanentSetaside, tov_Potatoes, tov_SeedGrass1, tov_SeedGrass2, tov_Setaside, tov_SpringBarley, tov_SpringRape, tov_Undefined, tov_WinterBarley, tov_WinterRape, tov_WinterWheat, tov_YoungForest, CfgBool::value(), MapErrorMsg::Warn(), and WARN_BUG.

Referenced by Init().

◆ Match_crop_to_field()

void OptimisingFarm::Match_crop_to_field ( LE a_field)

Finds a crop to be grown on a given field next year.

The function chooses a crop to grow in a given filed after the management plan of the current crop is finished.

  1. Creates a probability distribution of choosing rotational crops based on their planned areas (as percentages of a farm's area).
  2. Draws a number from the distribution and identifies which crop the number refers to.
  3. Checks if the crop is allowed to follow the current crop in a field, and if the difference between the field's area and crop's planned area is within acceptable range (to avoid growing too much of a given crop). If either of the conditions is not fulfilled, point 2 is repeated until a crop fulfilling both conditions is chosen. If this procedure fails in choosing a crop 20 times, the 2nd condition is released and the search is continued.
  4. If there is no crop fulfilling even just the 1st condition, the farm vector m_rotational_crops_copy is restarted, so that it includes all rotational crops a farmer wants to plant this year, including those that might have already been planted on other field this year.
  5. If there is still no crop that can follow a current crop, spring barley is grown (this situation happens when in the rotation there are only crops that can follow one specific crop, e.g. CloverGrassGrazed1 can follow only SpringBarley and CloverGrassGrazed2 can only follow CloverGrassGrazed1).
  6. When a crop to be grown is found, the function switches the rotation index to point to the crop placed in m_rotation before the chosen crop.
9161  {
9162 
9178  double field_size_pct = a_field->GetArea()/GetArea() * 100; //convert field size to pct of total arable farm area (a_rotational_crops will contain values of areas in %)
9179  TTypesOfVegetation current_crop =a_field->GetVegType();
9180  TTypesOfVegetation crop_to_grow = tov_Undefined;
9181 
9182  if(current_crop==tov_PermanentGrassGrazed || current_crop==tov_PermanentGrassTussocky || current_crop==tov_PermanentSetaside ||
9183  current_crop==tov_PermanentGrassLowYield || current_crop==tov_YoungForest || current_crop==tov_OrchardCrop) {
9184 
9185  crop_to_grow = current_crop; //and do not switch rot index - has to stay as it is to mark the field as perm
9186  }
9187  else{
9188 
9189  if((int)m_rotational_crops_copy.size()==0 ){ // in the 1st year it is empty since the choose dec. mode was not called yet!
9190  m_rotational_crops_copy = m_rotational_crops; //restart the copy - it is empty and we still need crops
9191  //debug
9192  if((int)m_rotational_crops_copy.size()==0){ //should not happen!
9193  char index[ 20 ];
9194  sprintf( index, "%d", m_almass_no);
9195  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): rot crops vector is empty! Farm no: ", index );
9196  exit( 1 );
9197  }
9198  }
9199 
9200  if (current_crop==tov_SeedGrass1){
9201  bool sg2=false;
9202  for(int i=0; i< (int)m_rotational_crops_copy.size(); i++){
9204  if(crop==tov_SeedGrass2) sg2 = true;
9205  }
9206  if (!sg2){ //there is no seedgrass2 in the list of crops. Otherwise just go to the normal procedure of choosing crop
9207  crop_to_grow = tov_SeedGrass2;
9208  }
9209  }
9210  if (current_crop==tov_CloverGrassGrazed1){
9211  bool cgg2=false;
9212  for(int i=0; i< (int)m_rotational_crops_copy.size(); i++){
9214  if(crop==tov_CloverGrassGrazed2) cgg2 = true;
9215  }
9216  if (!cgg2){ //there is no tov_CloverGrassGrazed2 in the list of crops. Otherwise just go to the normal procedure of choosing crop
9217  crop_to_grow = tov_CloverGrassGrazed2;
9218  }
9219  }
9220 
9221  if (current_crop!=tov_SpringBarley){
9222  bool other_crop_than_cgg = false;
9223  for(int i=0; i< (int)m_rotational_crops_copy.size(); i++){
9226  other_crop_than_cgg = true;
9227  break;
9228  }
9229  }
9230  if (!other_crop_than_cgg){ //there is no other tov than CGG1 or CGG2 in the list of crops. So need to grow smth which will fit - SB.
9231  crop_to_grow = tov_SpringBarley;
9232  }
9233  }
9234 
9235  bool Sb_inserted=false;
9236  if(crop_to_grow==tov_Undefined){ //if not, it is already CGG2 or SG
9237 
9238  //create the vector with numbers
9239  vector<int>probability_line;
9240  probability_line.push_back(0); //add the first element
9241  for(int i=0; i< (int)m_rotational_crops_copy.size(); i++){
9242  if(m_rotational_crops_copy[i].Number<0.5) m_rotational_crops_copy[i].Number += 0.5; //just in case - to avoid having crops that disappeear
9243  int area = (int)(m_rotational_crops_copy[i].Number + 0.5); //change to integer
9244  probability_line.push_back(area + (int)probability_line[probability_line.size() - 1]); //add a number equal to the sum of the current last element and this crop's area
9245  }
9246 
9247  //pick an index of a crop
9248  //see: http://en.cppreference.com/w/cpp/numeric/random/uniform_int_distribution
9249  std::random_device rd;
9250  std::mt19937 gen(rd());
9251  int last_number = probability_line[(int)probability_line.size() - 1]; //the last number
9252  distribution_type2 dis(0, last_number - 1);
9253  double crop_index = 0;
9254 
9255  double diff = 0;
9256  int index_j = 0;
9257  bool crop_found = false;
9258  for(int c = 0; !crop_found; c++){
9259  crop_index = dis(gen); //int from a range 0 - sum of crop areas in percent - only crops that haven't been grown yet - on their 'full' i.e. planned area
9260  //which crop is it?
9261  for(int j=0; j < (int)probability_line.size(); j++){
9262  if(j==(int)probability_line.size()-1) { //unless j=0 smth's wrong: we didnt find this index
9263  if(j==0){ //there are no crops left - prob. line contains just one element - 0.why?
9264  char index[ 20 ];
9265  sprintf( index, "%d", (int) crop_index);
9266  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): no crops left, index drawn is ", index );
9267  exit( 1 );
9268  }
9269  else{
9270  char index[ 20 ];
9271  sprintf( index, "%d", (int) crop_index);
9272  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): index not found in the prob. line", index );
9273  exit( 1 );
9274  }
9275  }
9276  if(crop_index >= probability_line[j] && crop_index < probability_line[j+1]) {
9277  if(j >= (int)m_rotational_crops_copy.size()) { //problem
9278  char index[ 20 ];
9279  sprintf( index, "%d", j);
9280  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): index out of a range", index );
9281  exit( 1 );
9282  }
9283  crop_to_grow = m_rotational_crops_copy[j].Tov;
9284  index_j = j;
9285  break; //got the crop type
9286  }
9287 
9288  }
9289  //make a check
9290  int lookup_before = m_OurManager->Get_lookup_table(current_crop * (tov_Undefined+1) + crop_to_grow); //check with a preceeding crop; tov_undef+1 - because this tov_undef is included in the lookup table
9291  if(lookup_before==-1){ //issue a warning: wrong index...
9292  char index[ 20 ];
9293  sprintf( index, "%d", current_crop);
9294  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): Error (possibly caused by a new tov type that is not incuded in the crops_lookup table) in reading the lookup table; tov type that should not appear: ", index );
9295  exit( 1 );
9296  }
9297  if(lookup_before==1){ //if so, make another check - but not if we tried already 20 times - then release this constraint
9298 
9299  bool WRape_grown = false;
9300  if(cfg_Areas_Based_on_Distribution.value()){ //then another check: spring rape cannot be grown if the farm grows winter rape within 1000 m (www.landbrugsinfo.dk)
9301  if(crop_to_grow == tov_SpringRape){
9302  for(int w=0; w<(int)m_fields.size(); w++){
9303  if(m_fields[w]->GetVegType() == tov_WinterRape) WRape_grown = true;
9304  }
9305  }
9306  }
9307 
9308  if(c<20){
9309  diff = field_size_pct - m_rotational_crops_copy[index_j].Number;
9310  if(diff <= 20 && !WRape_grown){ //diff in size smaller than 20 percent points - ok. Plus there is no winter rape around in case the chosen crop is SRape
9311  crop_found=true;
9312  break; //break the for - this crop is OK
9313  }
9314  }
9315  else{
9316  diff = field_size_pct - m_rotational_crops_copy[index_j].Number;
9317  if(!WRape_grown){
9318  crop_found=true; //this crop must be accepted
9319  break;
9320  }
9321  }
9322  }
9323  if(c==1000 && !crop_found){ //seems there's no crop that can follow the current one, so restart the crops instead and continue the search!
9324  m_rotational_crops_copy = m_rotational_crops; //restart - that's not enough - need a new prob line
9325  probability_line.clear();
9326  probability_line.push_back(0); //add the first element
9327  for(int i=0; i< (int)m_rotational_crops_copy.size(); i++){
9328  if(m_rotational_crops_copy[i].Number<0.5) m_rotational_crops_copy[i].Number += 0.5; //necessary to avoid having crop disappeeared
9329  int area = (int)(m_rotational_crops_copy[i].Number + 0.5); //change to integer
9330  probability_line.push_back(area + (int)probability_line[probability_line.size() - 1]); //add a number equal to the sum of the current last element and this crop's area
9331  }
9332 
9333  last_number = probability_line[(int)probability_line.size() - 1]; //the last number
9334  distribution_type2 dis(0, last_number - 1);
9335  }
9336  if(c>1500){ //seems there's no crop that can follow the current one - issue a warning; but now do this only after restarting
9337  #ifdef _DEBUG
9338  char index[ 20 ];
9339  sprintf( index, "%d", current_crop);
9340  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): There is no crop that can follow the current crop. Sbarley will be grown. The current crop is: ", index );
9341  #endif
9342  crop_to_grow=tov_SpringBarley;
9343  Sb_inserted=true;
9344  break;
9345  //exit( 1 );
9346  }
9347  }
9348 
9349  //crop found, so update the vector of crops
9350  if(!Sb_inserted){
9351  if(diff < 0){ //crop area should be larger than this field's area
9352  m_rotational_crops_copy[index_j].Number -= field_size_pct;
9353  }
9354  else{
9355  if(m_rotational_crops_copy.size() <1){ //smth is wrong
9356  char index[ 20 ];
9357  sprintf( index, "%d", current_crop);
9358  g_msg->Warn( WARN_BUG, "OptimisingFarm::Match_crop_to_field(): m_rotational_crops_copy is empty, the crop chosen is: ", index );
9359  exit( 1 );
9360  }
9361  m_rotational_crops_copy.erase(m_rotational_crops_copy.begin() + index_j);
9362  }
9363  }
9364  }
9365 
9366  //switch the rotational index:
9367 
9368  //1. find the chosen crop in the m_rotation
9369  int position_in_mrotation=-1;
9370  int size=(int)m_rotation.size();
9371 
9372  for(int c=0; c< (int)m_rotation.size(); c++){
9373  if(m_rotation[c] == crop_to_grow){
9374  position_in_mrotation=c;
9375  break;
9376  }
9377  }
9378 
9379  if(position_in_mrotation==-1){
9380  char error_num[ 20 ];
9381  sprintf( error_num, "%d", crop_to_grow );
9382  g_msg->Warn( WARN_FILE, "OptimisingFarm::Match_crop_to_field(): ""Unknown vegetation type:", error_num );
9383  exit( 1 );
9384  }
9385  //2. switch the rot index to a crop just before the chosen one
9386  if(position_in_mrotation!=0){
9387  a_field->SetRotIndex(position_in_mrotation-1);
9388  }
9389  else{
9390  a_field->SetRotIndex(size-1);
9391  }
9392  }//current crop is a rotational crop
9393 }
boost::random::uniform_int_distribution distribution_type2
Definition: BoostRandomGenerators.h:32

References cfg_Areas_Based_on_Distribution, g_msg, FarmManager::Get_lookup_table(), LE::GetArea(), Farm::GetArea(), LE::GetVegType(), m_almass_no, Farm::m_fields, Farm::m_OurManager, Farm::m_rotation, m_rotational_crops, m_rotational_crops_copy, LE::SetRotIndex(), tov_CloverGrassGrazed1, tov_CloverGrassGrazed2, tov_OrchardCrop, tov_PermanentGrassGrazed, tov_PermanentGrassLowYield, tov_PermanentGrassTussocky, tov_PermanentSetaside, tov_SeedGrass1, tov_SeedGrass2, tov_SpringBarley, tov_SpringRape, tov_Undefined, tov_WinterRape, tov_YoungForest, CfgBool::value(), MapErrorMsg::Warn(), WARN_BUG, and WARN_FILE.

Referenced by Crop::ChooseNextCrop().

◆ OptimiseFarm()

void OptimisingFarm::OptimiseFarm ( int  a_foobar)
protected

Carries out the whole farm optimisation.

5765  {
5766 
5767  optimizeCrops(a_foobar);